Slide 1

Slide 1 text

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

Slide 30

Slide 30 text

#dfua Setting up iOS project Xcode Project Default flow Java Source ObjC Source Static Library

Slide 31

Slide 31 text

#dfua Setting up iOS project Xcode Project Java Source ObjC Source Static Library GetSocial solution Python script

Slide 32

Slide 32 text

#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

Slide 34

Slide 34 text

#dfua Development process

Slide 35

Slide 35 text

#dfua Project structure workspace ├── build.gradle ├── android │ ├── android-demo/.. │ └── android-library/.. ├── ios │ ├── ios-demo/.. │ ├── ios-library/.. │ ├── ios-shared │ └── WORKSPACE.xcworkspace ├── lib │ ├── rx-java │ └── gson └── shared ├── src/.. └── build.gradle Shared code GetSocial case

Slide 36

Slide 36 text

#dfua Libraries sources Project structure workspace ├── build.gradle ├── android │ ├── android-demo/.. │ └── android-library/.. ├── ios │ ├── ios-demo/.. │ ├── ios-library/.. │ ├── ios-shared │ └── WORKSPACE.xcworkspace ├── lib │ ├── rx-java │ └── gson └── shared ├── lib/.. └── src/... GetSocial case

Slide 37

Slide 37 text

#dfua Project structure workspace ├── build.gradle ├── android │ ├── android-demo/.. │ └── android-library/.. ├── ios │ ├── ios-demo/.. │ ├── ios-library/.. │ ├── ios-shared │ └── WORKSPACE.xcworkspace ├── lib │ ├── rx-java │ └── gson └── shared ├── lib/.. └── src/... iOS code GetSocial case

Slide 38

Slide 38 text

#dfua Project structure workspace ├── build.gradle ├── android │ ├── android-demo/.. │ └── android-library/.. ├── ios │ ├── ios-demo/.. │ ├── ios-library/.. │ ├── ios-shared │ └── WORKSPACE.xcworkspace ├── lib │ ├── rx-java │ └── gson └── shared ├── lib/.. └── src/... GetSocial case Android code

Slide 39

Slide 39 text

#dfua

Slide 40

Slide 40 text

#dfua J2ObjC enforces Clean Architecture THE GOOD

Slide 41

Slide 41 text

#dfua Presentation Clean architecture Drivers Frameworks Domain Dependency Rule shared XXX-library XXX-demo

Slide 42

Slide 42 text

#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.

Slide 45

Slide 45 text

#dfua Check ported libs at j2objc-common-libs-e2e-test GitHub project Junit, Hamcrest, Mockito, Protobuf, Guava, Gson, Joda-time, commons-lang3, sqlighter-4 PORTED: AssertJ, RxJava, http libraries, DI, … MISSING: Libraries

Slide 46

Slide 46 text

#dfua Unit testing is the DNA of J2ObjC THE GOOD

Slide 47

Slide 47 text

#dfua High test coverage is the only way to confidence THE BAD

Slide 48

Slide 48 text

#dfua Testing • JUnit 3, 4 • Hamcrest 1.3 • Mockito 1.9.5 Toolchain

Slide 49

Slide 49 text

#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

Slide 59

Slide 59 text

#dfua Peak iOS Memory Performance Swift 1.2 J2ObjC J2ObjC (ARC) Xamarin RoboVM Usage, Mb 0 5 10 15 20 Performance Memory

Slide 60

Slide 60 text

#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