5

I plan to create an application on iOS, Android and a website with AngularJS.

But for not having to rewrite the business code on each app, I would like to reuse as much code as possible.

To be able to execute the core of the project on any platform, I have to use a web language.

Through different articles, I plan a common architecture to separate the business logic of the project - core - with the UI which will reimplemented for each system (UIKit for iOS, AngularJS and Polymer for the webapp, etc.)

The goal of this architecture is to respect important software engineering principles such as information hiding by decomposing requirements in modules, DRY and SOLID

  • Each feature will be decomposed in module.
  • Core: Business logic code - reusable on every platform - will be represented in form of a library.
  • View: The view class will be developed on each different platform to use the different UI elements proposed on each platform. E.g.: subclass of a ViewController in Objective-C / Swift for iOS or a simple class to manipulate HTML for the web-app. There is no logic in this class. It is only responsible to:
    • Handle user interactions to the business logic.
    • Display contents from the business logic
  • IView: Interface which abstracts the class which manipulates the view.
  • Presenter: Link between the Interactor and the View to drive the UI.
  • Interactor: The logic of the module, such as algorithms.
  • Data Store: Manage the persistence and the fetching of data by communicating with a database or API or web-service.
  • Model: Data represented in structures.

Here for iOS (almost the same for Android):

enter image description here

The code of "core" will be executed through a virtual machine as this article shows us: http://www.skyscanner.net/blogs/developing-mobile-cross-platform-library-part-3-javascript

Here for AngularJS:

https://docs.google.com/drawings/d/1NtdDfsr1yiuGOm_lfOY6Qab_kHb4I5b4sx7zeTAqwrE/pub?w=915&h=377


Now that you know everything about the architecture, here are my questions.

I don't have enough experiences and feedback on the web-langages to be able to make a smart choice. After few researches, I found that there are various options:

  • Dart:

    • Question 1: Are there mechanisms to allow interoperability between Objective-C/Swift and Java through VM? I know that both platforms have VM to execute Javascript code and Google provides dart2js to compile Dart to Javascript code. But it's not plain Javascript: See an example here. So I don't know if there is still a proper interoperability.
  • Javascript ES6: Event if it's not fully implemented in browsers yet, it's possible to start using ES6 with Traceur compiler.

    • Question 2: Is there interoperability of Javascript compiled by Traceur and the VM in iOS/Android?
    • Question 3: Is it "safe" to use ES6 through Traceur to develop a large-scale project and have production code?

Thank you for reading.

Jean Lebrument
  • 5,079
  • 8
  • 33
  • 67

3 Answers3

2

I know this wasn't one of the options you listed but don't automatically rule out C++. This is what Dropbox uses for example, they even open sourced their tools for this purpose:

C++ to Java/Objective-C API generator:

https://github.com/dropbox/djinni

Sample "native" app for Android/iOS:

https://github.com/libmx3/mx3

Interesting article on the subject with more links:

http://oleb.net/blog/2014/05/how-dropbox-uses-cplusplus-cross-platform-development/

Updated Answer:

If you really don't want to use C++ and are okay with the bloat you'll get from going non-native then you can try the following:

https://github.com/MobileChromeApps/mobile-chrome-apps

That project is Google's fork of Cordova and adds a bunch of new features and benefits.

There is a Dart wrapper over Chrome APIs here:

https://github.com/dart-gde/chrome.dart

Basically, you would write your app in Dart using plain HTML5 technologies, then for certain things you'd use the Chrome APIs (device state, etc). Then you can deploy:

  • Web: Compile to JavaScript without the Chrome API features.
  • Chrome OS: Compile to JavaScript with Chrome API features.
  • Android: Compile to JavaScript and then use MobileChromeApps to create Android app.
  • iOS: Compile to JavaScript and then use MobileChromeApps to create iOS app.
Lex Berezhny
  • 512
  • 3
  • 15
  • Thanks for your answer. But in my OP I'm also speaking about creating a web-app (website). CPP can't let me doing this. – Jean Lebrument Jan 29 '15 at 21:47
  • I would definitely use Dart for the web app. I've been using it successfully and am very happy with it. But I guess it depends on how much you appreciate a cleaner structure. If you can't live without classes and OOP then Dart is for you, but if you're happy with JavaScript/Prototype based programming than stick to JS. – Lex Berezhny Jan 29 '15 at 21:49
  • Yes, Dart is a really good language but I really wonder about the interaction between Dart and Java and Objective-C/Swift with the VM. Since Dart compiler compiles Dart into "optimized" Javascript, not "plain" Javascript, I don't know if interaction is still possible. – Jean Lebrument Jan 29 '15 at 22:04
  • I have updated my answer with details of how you can use Dart (or JS) for all deployment platforms. I'll only add that depending on the type of app you're building this may not be the most optimal stack. – Lex Berezhny Jan 30 '15 at 00:20
  • Thanks for your answer, but my objective is not to have to use third-party library to access to specific feature of each platform. My experience with third-party in cross-platform development learned me that using framework, and third-party libraries are great until you want to create something really specific and then you start to fight with the framework which was supposed to help you. I wish to create cross-platform app without the using of framework, only by using interaction through the VM. I am sure this is possible, I only wonder about how manage the interoperability with Dart and ES6 – Jean Lebrument Jan 30 '15 at 02:27
  • iOS does not allow any VM so that will be the biggest problem you'll have, I would start there. The only way to do what you want is go the compiled language route (this is a requirement on iOS) which means C, C++, etc. – Lex Berezhny Jan 30 '15 at 12:54
  • As you can see with the article from skyscanner in my OP or with this article: https://www.infinum.co/the-capsized-eight/articles/running-javascript-in-an-ios-application-with-javascriptcore There are already a JS VM in iOS and MacOS. Take a look on the skyscanner article because they provide a complete example of how execute Javascript in a native app. – Jean Lebrument Jan 30 '15 at 19:00
  • What I mean is that you are not allowed to bundle your own VM with your app. This means any custom JavaScript VMs or a Dart VM would not be allowed. The only one you have to work with is the one that comes on iOS (which is based on webkit javascript vm). If you go this route then you might as well use Cordova/MobileChromeApps because they already do exactly what you are trying to build (expose native APIs to JavaScript). – Lex Berezhny Jan 30 '15 at 22:22
  • I agree with you but what about other platform such as windows phone, windows "desktop" and MacOS? I'm at the very beginning of my project and I could extend the app to desktop versions. So I would like to not use third-party library / framework that could potentially cause problems in a second time. – Jean Lebrument Jan 31 '15 at 01:38
  • I'm going to stick with the answer I provided: If you build your domain logic in C++ you can deploy natively to Android, iOS, Mac, Linux, Windows and Windows Phone; you just do the native UI for each platform which interfaces with your C++ lib. If you do not want to go that route than JavaScript/Dart/other js translatable language is your only option, used with something like Cordova/ChromeMobileApps. – Lex Berezhny Jan 31 '15 at 02:38
1

This is an interesting topic. Here is what I learnt from the "GWT.Create" conference, the google guys showed how they did the cross platforms project:

First the DataStore and Model part in your picture should be done in an external server, so it's already crossed platforms.

UI render must be done in native way individually, that's the best solution.

They implemented the shared logic (complicated calculation, encryption, etc) with Java, for Android it works out of box, for Web they use GWT to translate Java to Javascript and for iOS they use J2ObjC, a new Google product. You can find it here:

https://github.com/google/j2objc

They also mentioned the C/Cpp solution, it's not a bad idea at all, Java is just a high level language and easy to use in most case.

cn123h
  • 2,302
  • 1
  • 21
  • 16
  • Thanks for your answer. The "core" on the scheme will be developed in a static library and the views will be done in native way individually. Java is a good option, but I would like to remind you that I would like to create a website too and using the "core" as well in the website. Moreover, I think it could be a good idea to start this project with new famous languages such as Dart (for the core), Swift (iOS view), Go (Android view) and AngularDart or AngularJS (website view) – Jean Lebrument Feb 07 '15 at 21:51
1

If you want to create a cross platform application (iOS/Android/Web) the best thing you can do is sharing as much code as possible between these platforms. You could use something like PhoneGap/Cordova but this does not feel very native all the time. Event the best PhoneGap app feels not that native because it does not use the native UI. Instead in embeds a browser in a native UI container.

What I recommend is using a project structure as follows:

  • myapp-core
  • myapp-ios
  • myapp-android
  • myapp-web

The the core project is shared between the ios, android and web project. You can write the core project in Java and use GWT to translate this code into JavaScript for the web project. For the android project there is nothing to do because Android uses Java. For your ios project you can use J2Objc to transpile you core Java code into Objective-C.

What come into the core project?

Use interfaces and abstract base classes as well as factories as much as you can.

conversations, reminders, and contacts It also deals with the difficult task of network management and offline synchronization, where the app is used offline, reminders are made, and e-mails are sent. It's up to the app to store all that and fire it off to the Internet when the time comes. Source

Of course, there are a number of elements of Inbox that are shared across the three platforms: code for managing network communication, caching objects, local persistent storage, managing user edits both locally and remotely, and supporting it all while offline. This logic must be faithfully and correctly implemented and kept up to date on all three clients. Rewriting it three times in three different languages would soak up substantial engineering resources and slow down how quickly we make improvements to Inbox.

For iOS we developed the now open source J2ObjC cross compiler to translate our Java data model to Objective-C, and again we get a natural API on which to build our native iOS Inbox app (complete with -[Reminder snooze]). The astute reader may wonder how we deal with the impedance mismatch when translating from a garbage collected language (Java) to a reference counted one (Objective-C). Generally, J2ObjC relies on Objective-C autorelease pools, so objects normally garbage-collected are instead freed when a pool drains. One problem with this approach is reference cycles; in places that cycles exist in our Java data model, we use a Java annotation to identify the @WeakReference. When transpiled, the corresponding property in Objective-C will have the __weak modifier, thus breaking the retain cycle. In practice we’ve found this to be a relatively minor problem and we have automation tests that flag the rare cases of new cycles creeping into the object model. Source

The communication between your core modules can be done with Dagger2 it runs on Android/iOS/GWT. There is also a cross platform JSON library called realtime-json. The HTTP transport can be implemented in the core at least for Android and iOS. Form GWT/JavaScript you have to do it on the client side.

Here are some sample apps that should help you:

Michael
  • 32,527
  • 49
  • 210
  • 370