Cross platform development - Google way
J2ObjC
Vitaliy Zasadnyy
Head of Mobile @ GetSocial
Slide 2
Slide 2 text
In yellow boxes like this one you can find comments to
the slide.
Enjoy the presentation and if you have any questions,
feel free to reach me at [email protected]
Slide 3
Slide 3 text
#dfua
hard
Cross platform development is
Slide 4
Slide 4 text
#dfua
70%
code reuse
Source: Gmail Blog
Slide 5
Slide 5 text
#dfua
25+ projects
Google is using J2ObjC for almost all office apps.
Besides Google, more than 25 projects claimed using
J2ObjC.
Slide 6
Slide 6 text
Now I’m leading mobile department at Dutch startup
GetSocial
Slide 7
Slide 7 text
With help of GetSocial SDK you can add Activity Feed,
Chat, Notifications or Smart Invites just with a few lines
of code
Slide 8
Slide 8 text
SDK is available for Android, iOS, Unity and Cordova
Slide 9
Slide 9 text
30M
50+ 500M
APPS & GAMES MONTHLY USERS TOTAL SESSIONS
With over 50 integrated apps, GetSocial serve 30
million users every month that generated half a billion
sessions during 2015.
Slide 10
Slide 10 text
#dfua
GetSocial SDK architecture
Android
SDK
iOS
SDK
iOS Bridge Android Bridge
C# API
Unity SDK
Java Objective C C#
We have Android and iOS SDKs built
natively using Java and Objective C
respectively. Unity SDK is a thin
bridge layer that forwards calls from
public interface exposed in C# to
native implementation
Slide 11
Slide 11 text
#dfua
GetSocial SDK architecture
THE GOOD:
• Easy to leverage all platform features
• Doing work twice
• Hard to keep in sync API behaviour
THE BAD:
The biggest advantage of having pure native SDK -
being able to use low level platform features.
Disadvantage - all features are implemented twice
(longer time to market), also it’s hard to keep
behaviour in sync, coz each developer has unique way
to solve problems.
Slide 12
Slide 12 text
–Sun Microsystems
Write once, run everywhere
“
We decided to look around on possible solutions, to
reach ultimate goal, write code once and run it
everywhere.
Slide 13
Slide 13 text
#dfua
Requirements
Maintainability
Performance
Size footprint Licensing
Requirements for the solution:
- performance should be at least the same as on native
- code should be easy to maintain (reliable toolchain)
- SDK should keep reasonable size
- ideally solution should be free and compatible with
our distribution model
Slide 14
Slide 14 text
#dfua
J2ObjC
Xamarin XmlVM
RoboVM
We did a research on what tools were available on a
market. Some were not performant enough, some
were not suitable for SDK development.
Slide 15
Slide 15 text
#dfua
J2ObjC
All except J2ObjC.
Project started and actively developed by Google.
Inbox built with J2ObjC.
We started an internal RnD project to research if
J2ObjC can fit with our requirements.
Slide 16
Slide 16 text
#dfua
Dive into J2ObjC
Let’s look more close on the key features of J2ObjC.
Slide 17
Slide 17 text
J2ObjC - WTF?
Build configuration
Development process
Project impact
The grand plan
@zasadnyy
Slide 18
Slide 18 text
#dfua
What is J2ObjC?
• Source-to-source compiler
• Focus on shared business logic
• Apache 2 Licence
Slide 19
Slide 19 text
#dfua
• NOT cross-platform application tool
• NOT platform-independent UI toolkit
• NOT Java emulator
• NOT one time source translation
What J2ObjC isn’t
Slide 20
Slide 20 text
#dfua
Is it production ready?
v1.0.0
January 21, 2016
Slide 21
Slide 21 text
#dfua
What is supported?
• Full Java 7 syntax
• Inner classes, enums, annotations…
• Reflection
• JUnit test translation
• OCNI code embedding
J2ObjC engineers did a great job, they reimplemented
Java paradigms like inner classes, enums, annotations
and reflection on Objective C, where they are not
available.
Slide 22
Slide 22 text
#dfua
OCNI code embedding
static native void log(String text) /*-[
NSLog(@"%@", text);
]-*/;
Java code
You can embed Objective C code in Java in a special
comments.
Slide 23
Slide 23 text
#dfua
OCNI code embedding
static native void log(String text) /*-[
NSLog(@"%@", text);
]-*/;
+ (void)log: (NSString*)text {
NSLog(@"%@", text);
}
Translated code
DON’T do that, little bunnies die each time you’re using
OCNI.
Slide 24
Slide 24 text
#dfua
Build configuration
Slide 25
Slide 25 text
#dfua
How to use
$ j2objc DevFest.java
$ ls
DevFest.h DevFest.m
translating DevFest.java
Translated 1 file: 0 errors, 0 warnings
j2objc is a command line tool, you’re going to work
with to perform translation from Java to Objective C.
It’s very powerful, but not very convenient to use on a
real projects, coz amount of passed parameters will
explode.
Slide 26
Slide 26 text
#dfua
Available plugins
Make Eclipse Gradle
Maven
J2ObjC provide a plugins for most part of popular build
tools.
We’re going to focus on Gradle plugin.
Slide 27
Slide 27 text
#dfua
Gradle plugin
• Easy integration
• State of art codebase
The good
Bruno Bowden Advay Mengle
• Rockstar authors
Slide 28
Slide 28 text
#dfua
Gradle plugin
• As of July 25 is not supported
• Last supported J2ObjC version is 0.9.8.2.1
• Last supported Gradle version is 2.8
• Check our fork at
https://github.com/getsocial-rnd/j2objc-gradle
The bad
Main problem with j2objc-gradle plugin - it supports
only Gradle up to v2.8. Android on the other hand to
support latest features requires 2.9+. Big part of plugin
need to be rewritten to support new project model
introduced in 2.9.
Slide 29
Slide 29 text
#dfua
Setting up iOS project
• Automatically via CocoaPods
• Manually link binaries
THE GOOD:
THE BAD:
• Impossible debug
#dfua
Build time optimisations
• Build only debug binaries
• Include only target processor architectures
Default: ios_arm64,ios_armv7,ios_x86_64
• Set up single platform builds
Slide 33
Slide 33 text
#dfua
6
min
<2
min
*Android + J2ObjC build
GetSocial case
Build time optimisations
#dfua
Libraries
• Sources required
• Not all java packages implemented
• Tests are highly recommended
Slide 43
Slide 43 text
#dfua
dependencies {
compile ‘com.google.code.gson:gson:2.6.2’
}
j2objcConfig {
autoConfigureDeps true
}
Libraries
shared/build.gradle
If OOS library has sources and test published together
with a binaries, you can ask j2objc plugin to pull them
and cross compile. But we managed to get it working
only for Gson.
Slide 44
Slide 44 text
#dfua
workspace
├──...
├── lib
│ └── rx-java
│ └── build.gradle
└── shared
└── build.gradle
GetSocial solution
Libraries
Set-up J2ObjC
translation
Include library
project
More universal way is to create a new project with
library, set up j2objc cross compilation for a project
and include it as a dependency into shared module.
#dfua
• Narrow selection of testing libs/frameworks
• Util classes in tests are being executed => FAIL
• Thread.sleep(0) hangs
Testing
The bad
The easiest way to solve the problem with util classes
being run as test is to agree on convention of Test
suffix for all text classes + providing exclude pattern for
tests in j2objc grade plugin config
Slide 50
Slide 50 text
#dfua
Name mangling
package com.zasadnyy.reddit.model;
public class RedditDataManager {…}
@interface ComZasadnyyRedditModelRedditDataManager
: NSObject
Translates to
Class names
Check the demo repo for more examples
Slide 51
Slide 51 text
#dfua
Name mangling
String foo(int i);
- (NSString *)fooWithInt:(jint)i;
Translates to
METHODS
Slide 52
Slide 52 text
#dfua
Name mangling
The good
j2objcConfig {
translateArgs '--prefixes', 'packagePrefixes.properties'
translateArgs '--mapping', 'methodMapping.properties'
}
• @ObjectiveCName(“”)
• Method/package mapping configurations
Gradle plugin provides configuration closure to setup
package and method names mappings
Slide 53
Slide 53 text
#dfua
Name mangling
The bad
RedditDataManager.init(Ljava/lang/String;)V =
VzRedditDataManager initWithAppId:(NSString)appId
Method mappings are fragile
Any refactoring of the method or change in package
mappings will break your method mapping configuration
Slide 54
Slide 54 text
#dfua
Name mangling
GetSocial solution
Package
prefixes
Set of
wrappers
+
We ended up using package mapping + wrapping all
generated code on the ObjC side
Slide 55
Slide 55 text
#dfua
Project Impact
Slide 56
Slide 56 text
#dfua
Performance
Make simple computations on
the array of 600 GPS coordinates 1,000 times
Testing method:
Computational
Source: Medium post by Harry Cheung
Slide 57
Slide 57 text
#dfua
Computational
Average iOS Computational Performance
Swift 1.2
J2ObjC
J2ObjC (ARC)
Xamarin
RoboVM
Time, s
0 0,275 0,55 0,825 1,1
Performance
Slide 58
Slide 58 text
#dfua
Make simple computations on
the array of 600 GPS coordinates 10,000 times
Testing method:
Source: Medium post by Harry Cheung
Performance
Memory
#dfua
iOS app size impact
3Mb Extra (1 target platform)
Reduce size:
• Include only required parts of jre_emul.a
• Shrink unused Java code with Proguard
3Mb is mainly a size of translated JRE library that
should be included with your project.
Slide 61
Slide 61 text
#dfua
Team impact
• iOS Developers have way less work
• Developers should be familiar with both platforms
Slide 62
Slide 62 text
#dfua
At a glance
Slide 63
Slide 63 text
#dfua
At a glance
• Unsupported Gradle plugin
• Limitations on dependencies
• Unit tests as the only way to validate logic
THE BAD:
Slide 64
Slide 64 text
#dfua
At a glance
THE GOOD:
• Performance
• Maintainability
• Reasonable size footprint
• Apache License
• Clean architecture
Slide 65
Slide 65 text
#dfua
64%
code reuse
At a glance
Slide 66
Slide 66 text
Thank you!
Questions?
Vitaliy Zasadnyy
@zasadnyy
Slides will be available at:
v.zasadnyy.com/slides/
Дякую за увагу!
Slide 67
Slide 67 text
#dfua
We are hiring ninjas!
• Android (UA/NL)
• Golang (UA)
Slide 68
Slide 68 text
#dfua
Resources
• Official J2ObjC website
• J2ObjC on GitHub
• J2ObjC Gradle Plugin on GitHub
• GitHub project with end-to-end test of compatible libraries
• Goodow GitHub account with several J2ObjC related repos
• Cross platform frameworks performance tests
• Demo project