J2Objc Cross‑Platform Technology: Making iOS and Android Play Nice
One of the biggest challenges for mobile developers is to create an app for both iOS and Android, or in other words, to make them play nice. It’s hard enough to create a cross-platform product when the only difference is the sdk/framework. But it’s even worse for iOS and Android since the available native languages are a disjoint set. Fortunately, some new technologies for iOS/Android cross-platform development have been maturing to the point that we felt it was worthwhile to investigate.
In the last couple of weeks, some of my colleagues and I have been test-driving the Java-to-ObjectiveC (j2Objc) cross-compiler developed at Google. The compiler translates standard Java source code to Objective C (ObjC) source code, which can then be included in an Xcode project. The compiler makes no attempt to handle GUI code, feeling that GUI is best done natively to preserve the look and feel that each platform’s users expect. But this still leaves plenty of room to share data model code across platforms. Since the data model is often the most complex code in an application, leveraging this code can be quite a savings.
To give the compiler an honest test, we copied the Java data model code from one of our clients and then built a complete, albeit modest, application on top of it. The Java made extensive use of HttpURLConnection, gson, and the standard Java collections and library. So we felt this was a reasonable trial.
While there was a bit of a curve learning with what to expect from the j2Objc generated code, we really had to do very little to allow the compiler to create useable ObjC source. With one exception, which I’ll discuss below, any correct Java we threw at j2Objc compiled into equivalent (and compilable) ObjC source.
From the iOS side, I have just two minor grumbles. Java list objects don’t allow subscript access for iOS. This is unfortunate since it’s so easy to provide subscript access in recent versions of ObjC. Implementing - (id)objectAtIndexedSubscript:(NSUInteger)idx in a class allows subscript access on class instances like someClass. The good news is that when I mentioned this issue on the j2Objc forum, I was informed that they would add this feature in an upcoming release. Now that’s responsive!
The other issue is that Java’s standard forget accessor names is different from ObjC. Although I was disappointed at first, this turned out to be a minor nit. Java uses getName or isName. Where ObjC uses a bare name for the getter i.e., the getter method name is the same as the instance variable. The result is that you can’t use dot notation for j2Objc-generated getters. You must use method calls: [someClass getSomeValue]; vs. someClass.someValue;
The one instance where j2Objc failed was when we tried to translate the Spring framework. It kept dying in dependency hell. I emphasize that we didn’t try all that hard to get it working since we felt that Spring was completely unnecessary to the problem domain. I would say that our success in creating the POC application shows that we were correct in that assessment!
The bar to try j2Objc is really low. Setting up the j2Objc project took just a few hours, once our Java guy had read the docs. For additional how-tos, take a look at the j2Objc site and the forums.
I would encourage anyone who wants to deliver both iOS and Android versions of their app to give j2Objc a try. The results were completely successful. Our test iOS application had no trouble accessing the generated data model code. The application is useable, does useful work, and proved that it’s possible for iOS and Android to get along!