Home Features Docs Blog Support GitHub

Packaging MOE project as Framework/CocoaPod - Reloaded


(Roy Dalal) #1

I am posting again since I was not able to get any kind of adequate support whatsoever, and I wouldn’t want months of work working on MOE to go to waste. So here goes:

Hello,
I read several threads about packaging an MOE project as an SDK to be used in a non-MOE Xcode project.
I saw that there were plans to add this capability to MOE 1.3, but haven’t seen any concrete reference to it.

So to boil it down I have three questions:

  • Does this capability exist? Is it possible to package an MOE project as an SDK to be used in non-MOE Xcode projects?
  • If not, what would be the best way to do so?
  • What would it require from a developer that wishes to integrate this SDK? Will they have to actively install the MOE framework? Etc.

There are several threads from months back discussing it, I want to make sure we are following the latest best-practices.

Thank you,
Roy


(Gergely Kis - Migeran) #2

Dear Roy,

sorry for the terribly long time to respond to your question. I actually found an old answer of mine where I answered this issue in detail:

To summarize:

  • It is currently not possible to package a MOE project as a Framework, but you can get relatively close to it, because MOE only needs very few changes to an Xcode project (not more than what CocoaPods does), and we have the tooling implemented in the Gradle plugin to do it.
  • You cannot hide the fact, that your library is using MOE, because of the above changes and how the current version of MOE links the compiled Java code into your final app binary.
  • If you have a Java library that you made accessible from Objective-C using one of the methods outlined in the previous post, then for someone else to install it into a non-MOE Xcode project, they would need to:
  1. Create a Java project structure with a build.gradle file that pulled in the MOE plugin and included the moe section as outlined in the other post, specifically to point to the Xcode project / workspace you want to use. The default path for this is under the xcode folder in the Java project root, but it should work with other paths.
  2. Execute the moeUpdateXcodeSettings gradle task to make the necessary changes to the Xcode project.
  3. In the build.gradle file you can add the necessary configuration to include your Java code. You also need to decide how you want to initialize your Java library from the native part of your project, there are multiple options for that, but the easiest solution is to call moevm() from your main() function, and moevm() will start your main Java class specified in your Info.plist, and this class can just call UIApplicationMain with an AppDelegate. This default main() method is generated for any MOE project created using the Android Studio plugin, that you can use as a reference.
  4. This AppDelegate can be implemented in any language (e.g. Swift or Objective-C) it does not have to be Java - so here you can transfer the control back to the native application part.
  5. If your Java code requires initialization, you could add that code to your main Java class before UIApplicationMain() is called.

At this point you can just use Xcode to build and run the whole application, without ever entering Android Studio again. It will compile the Java parts too and link them into your app.

If you want to distribute your library to 3rd parties, you could create a script for them that takes an Xcode project, and converts it to a project where your Java library is already included and configured. The heavy lifting of modifying the Xcode project is done inside the Gradle task automatically.

While not as simple as just adding a simple CocoaPod dependency, in my opinion it is still a pretty straightforward process. The MOE framework still needs to be pulled into the app, but it is done automatically at build time.

Now there is potential of this to become much easier in a future version of MOE, when we move to position independent code for the compiled Java code, which was added to newer versions of ART. This could mean that a Java application can be compiled into a regular shared library (with some additional resources), and packaged as a normal framework that can be added as a CocoaPod dependency, with a transitive dependency to MOE.framework. But this is not implemented at this time, and I can’t give you a timeline when this will be implemented.

If you have any more questions, don’t hesitate to ask.

Best Regards,
Gergely