Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
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):
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:
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.
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.
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.
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:
iOs App showing J2Objc: https://github.com/tomball/j2objc-sample-reversi
Starter Kit for Hybrid apps: https://github.com/Sfeir/jhybrid
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I develop an app for both iOS and Android, and I'm loon'ing for the best way to share code between this two platforms.
What I would like to do is creating all the View (UI part) in native but share the code for the logic (controller + model).
With all I found, 3 things seems to be quite good :
1) C++ --> Build library file Using c++ For the logic so I'll be able To use the .dll files in the 2 platforms
2) Azure mobile apps services. Is it possible to habe all the logic in a webservice? The issue is that if I dont have acces to internet, my app will be unaivalable, right?
3) I hear a lot about React native used by Facebook, but it seems to be used to create the UI, but I prever create it in native. Can I use react only for logic?
It seems like you have three options:
1. C++
You can't just have a compiled .dll and expect it to work for iOS and Android. They both have to be compiled in different architectures and it has to be a static library on iOS.
Dropbox's done it this way, and they've put up a lot of notes and example code, and code you can use so you can take a look.
Pros
• Pretty straightforward after you manage to set it up
• No additional layer of dependencies, bugs, etc (like in case of Xamarin/React Native)
Cons
• Setting it up and using it needs a lot of extra work: you need to setup additional compile steps and write wrappers for both platforms.
• Some other challenges you're surely going to meet when trying to compile the same code for two different architectures
Here's a SO post on how to do it in detail...
2. Xamarin
This option seems to extreme to use in this case. You're forced to use C# and introduce another layer of dependencies and bugs. You said you don't want to use another language for UI so I wouldn't recommend it.
3. React Native
Now this is a viable option. You can write scripts in JS and use them in native code in both Android and iOS.
Here's an article on how to share code with code examples...
Unfortunately it uses React Native for UI, but you can easily call React Native functions from native code.
There are a lot of downfalls to using this, including the fact that the calls are asynchronous as they're executed on another thread, so you would have to implement some kind of callback system for functions that return something.
Pros
• Seems to be easy to set up and write
Cons
• You'd have to implement a native callback for every function that returns something
• Using it has a lot of downfalls that the document describes:
• As events can be sent from anywhere, they can introduce
spaghetti-style dependencies into your project.
• Events share namespace, which means that you may encounter some name
collisions. Collisions will not be detected statically, what makes
them hard to debug.
• If you use several instances of the same React Native component and
you want to distinguish them from the perspective of your event,
you'll likely need to introduce some kind of identifiers and pass them
along with events (you can use the native view's reactTag as an
identifier).
Conclusion
I think I'd go with C++, mainly because a big company (Dropbox) tried it and succeeded and actually uses it in production. You could try React Native as an experiment, it would make a great study case!
I'd say that putting the "core" logic into a separate library is a sensible approach.
You are not the first who wants to do this, and I highly recommend looking at Djinni. It's a tool to accomplish just that. You can define common interfaces and datatypes and fill in the native parts. Communication is possible in both ways.
It's not as easy as writing the whole thing natively at once, but it supports clean design which you might benefit from anyway.
I am currently planning the development of a multiplatform app, and I am not sure wich way to do it fits my requirements best, since all possibilties I could think of failed to satisfy me.
First I want to write an app for android, which should feel like a normal typical android app. So I want to use the standard actionbar and android design look and feel in my other gui elements. After finishing the android app I am planning on developing an ios app, which should have a different design, so i am going to redevelop the gui for this anyway.
But I don´t want to rewrite the other code wich represents the intelligence of the app, independent from the gui. I came up with the following possibilities:
1. Java GUI With native library
Here I abstract all the code of my app in a C++ library (since as far as I know ios supports the usage of c++ libraries too) and develop the gui android typically in java. The library would than have a function to start and would inform the gui about every change via callback functions.
Pro
I can reuse all the code that would be the same on both platforms. I just would implement the gui seperately
The design of the android gui is straightforward as I want it to be. It looks like typical android because it is typical android.
Cons
I dislike the usage of JNI very much. Especially the signature and names of the callback functions (calling java functions from c++) are not checked at compile time and require a lot of manual work. If I rename a function and forget to rework the native part I only notice this mistake at runtime.
2. Build the GUI on the native side
Here I had difficulties finding out what is possible, especially for 2.2
2.1 Use Qt
I have only a few first step experiences with Qt in general but as far as I understood i would have the following pros and cons:
Pro
Reuse most parts of the code for ios and Android. I would than redesign the gui for each platform to make them feel natural. I can´t evaluate how much qt may even assists me at doing that
Cons
I have to copy the android gui by using other qt widgets. This is more effort and I don´t know if one can replicate the android gui elements (like the actionbar) so that the user wouldn´t notice it.
2.2 Using the android framework from the native side
I dont know if this is possible at all, I wasn´t able to find this information. Can I use the class "NativeActivity" and use the android framework to build the gui and use e.g. the actionbar? If this is possible somehow it would have the pros from 1. and maybe wouldn´t have it cons?
Do you have any feedback to my ideas or maybe even new approaches I didn´t think of? How do other multiplatform apps like WhatsApp solve this problem? Do they have redundant code for each platform?
Thank you,
Tobi
I would say that it depends very much on your application requirements. By my opinion, a better solution is to develop a separate application for each platform using recommended SDK's for that platform, and implement in native C++ only the time consuming data processing algorithms.
Application runtime on mobile platforms is not so straightforward as on desktop platforms. You should take into account background and foreground processing, specific application life cycling, accessing system resources such as network, file system, etc. And all these issues do differ on iOS and Android.
Regarding possibilities that you listed.
Qt/QML is ok only in case two requirements are met:
1.1 Your application is a foregroud application without any background operations.
1.2 You purchase a commercial Qt license because only commercial Qt can be submitted to Apple iTunes app store (even GPL apps are under
question).
Using NDK Native Activities on Android with cross-platform C/C++ backend. Android NDK API offers much less API then Android Java SDK, so a lot of things you will have to implement or wrap manually. It is a hard road.
Mixing Java code and C/C++ using JNI gives you more of Android SDK API. But you should remember that an Android activity's life cycle is not somewhat that you're used to deal with when developing on C/C++.
Approach that we are using
We've been developing an application with a huge amount of cross platform functionality that should work on Windows/Linux/Mac OSx/Android/iOS. We're using the approach as follows.
Cross-platform core is written in pure C++.
We have adaptors to GUI interface for each platform.
On desktop we use Qt as it reaches all desktop platforms with minor adapting to each platform.
On iOS the GUI is built using iOS SDK with Objective-C and C++ core is linked as a Framework. Still, we had to patch our core in some way for iOS background requirements and so.
On Android we wrap our C++ core in a background process and build all the GUI using only Android Java SDK. Foreground GUI activities interact with the core via local sockets, so we don't need to bother with activities life cycling in our C++ core. But the adaptor is a litle bit complicated.
Nevertheless, both mobile platforms often require workarounds and adaptations in C++ core which add a number of #ifdef'ed branches in code for each platform.
I've been searching solutions for my enterprise apps, at least 3 platforms need to be supported, which are iOS, Android and Window Phone. After a whole day's search, I finally set my eyes on 2 promising cross platform solutions, one is monocross and the other phonegap.
monocross seems to use c# and .net at all, is it possible to access native libraries and languages? I read somewhere it's compiled directly into binaries that can execute on target platforms.
And about phonegap, it uses webviews on each platform to provide the capabilities of presenting user interfaces to final users. As it's implemented via interpreted language and high level apis, the performance may not meet our needs.
Finally, we(my team) decide to give it a try with mono, the architecture is illustrated as bellow:
+++++++++++++++++++++representation layer++++++++++++++++++++++++++
[monotouch,monodroid,silverlight]or [native gui calls] or [html5/js/css]
+++++++++++++representation controller/business logic layer+++++++++++++++
[ mono/c# ]
++++++++++++++++++++++++++++server side+++++++++++++++++++++++++++
[ the cloud ]
I want to use mono/c# to write some common purpose business logic and data structures, and when it comes to some common platform features, like storage service, notifications, I'd like to wrap them up on each platform and expose uniform apis for c#(business logic layer) to use. As to the representation layer, we decide to choose from the 3 optional solutions listed above.
To make this happening, first I have to figure out if it is possible to call native frameworks.
So, my questions are:
1, How does mono work, I mean, are the c# codes compiled into binaries that can be executed directly on iOS, Android and Windows Phone?
2, Is there a mechanism to make native invocations? Like in cocos2d-x, I can call java methods via JNI, and in iOS, c++ can call oc directly. Can I call cocoa touch stuffs in mono with c#?
3, Is it possible to manage all these stuffs in one single project, and how to build them?
4, Are there any better solutions?
Any suggestions will be appreciated, thanks for your patience!
I wonder why Xamarin does not land on the first page of your search result,
http://xamarin.com/features
But that's what the Mono guys created for the C# developers that want to target mobile platforms. MonoTouch and Mono for Android are there each featuring a common library base with Microsoft .NET, and also platform specific bindings.
Your non-UI code should be able to be used in portable libraries and share among them. Microsoft's portable library is Windows specific, and right now I am not sure how much Mono guys can embrace that, but even if PCL fails, you can create multiple platform specific projects based on the same copy of source files (which I did in #SNMP). The remaining task is to develop platform specific UI for Windows Phone, iOS, and Android.
There are tons of articles showing the features,
http://docs.xamarin.com/
and also many successful apps
http://xamarin.com/apps
The best way to learn a product is to try it out (for free in Xamarin's case). This also applies to MonoCross (which is a framework built upon Mono).
I am not familiar with PhoneGap, so you need someone's advice on that.
Disclaimer: this is not a complete answer - but I do hope it answers at least part of your question
I encountered a similar problem when I started cross-platform dev using the Mono products 18 months ago.
The approach I've built since is called MvvmCross - it forked off of MonoCross a long time ago - now shares no code with it (but maybe we'll team up again one day!).
The approach uses PCLs to share code. This is not entirely painless, but is easy after you've done a few setup steps - http://slodge.blogspot.co.uk/2012/12/cross-platform-winrt-monodroid.html
You can learn more about this approach on this video: http://slodge.blogspot.co.uk/2012/12/mvvmcross-video-presentation-xaminar.html
We've begun to build Cross platform Android/iOS apps, having built exclusively in MonoTouch before. We're evaluating MonoDroid.
Our apps need to consume JSON and we'd like to use ServiceStack. Xamarin has a ServiceStack branch which we're using - https://github.com/xamarin/ServiceStack
We'd like to have a common project responsible for GETting and POSTing JSON. ServiceStack by Xamarin has different DLLs for Android and iOS. How do we have a single project and use ServiceStack to get at our JSON?
We're open to other options to get at JSON in a unified way?
By and large, managed *.dll's compiled for MonoTouch that don't have a dependency on MonoTouch specific types are compatible with Mono for Android projects.
ServiceStack is a great example of this. I've personally used it for multiple projects across the Xamarin mobile framework offerings.
As a general rule I tend to encapsulate all invocation to my web services using a partial class with async methods, like FooProjectRestClient. And then if there ever is any sort of segmentation that needs to occur it can happen in a shared class using #if defs.
The reason why there are MonoTouch and Mono for Android specific libraries is often because of the (smaller, Silverlight-like) profile available (e.g. things that depends on new FX4.0 features needs to be cut out). They are often the same code re-compiled with SILVERLIGHT (or MONOTOUCH, MONODROID) defined.
The reason for MonoTouch only specific librairies are generally because its environment (iOS devices) do not allow JIT'ing. So there's no code generation (e.g. System.Reflection.Emit) or dynamically (down)loading code... However it's often possible to provide (less performant) workarounds or skip a few features and keep a special version of the library for MonoTouch.
Now back to having a single shared assembly/project. The special MonoTouch assembly (generally the same code re-compiled with MONOTOUCH defined) is still a valid .NET assembly and often can be used in Mono for Android, Mono or .NET (once recompiled, even with MONOTOUCH). It's definitively not optimal but it's something you can try.
Another one is having the same projects (e.g. MyLib), across several solutions (e.g. MonoTouchApp, M4AndroidApp) and use special configurations (just like there's an iPhone|Debug one) to set different defines (e.g. MONOTOUCH on iPhone*|*). That can allow you to keep the best feature implementation in each platforms (e.g. in case the same feature is implemented differently).
I would try the later first (config), then sharing the MonoTouch special assembly and finally (if it really does not work) look for other alternatives.
I've been hired to develop a mobile framework for a webservice created by my employer. Ideally management would like to have some reusable components that can be shared across mobile platforms (initially iOS & Android, probably Windows Phone 7 at some later point).
I've been wondering how feasible this is. One of the requirements is a native interface, so we would use Cocoa Touch on iOS & whatever (Java-based) toolset is used to create a native UI for Android. The application will interact with webservices, mainly the ones that we've been creating internally. The webservices have been developed in .NET.
As far as reusable components go, I guess we could use some C++ code to make webservice calls and perhaps even more of the backend of an application, yet I wonder if this would be a good approach. Apple's Foundation Framework has some excellent capabilities build-in to access webservices, not to mention other open-source libraries, e.g. ASIHttpRequest, SBJSON, etc... I guess the same would be true for Android (though I have no real Android experience for now). Also, when looking at projects done by companies like Google, Twitter & Facebook, each of these companies offers native libraries built for the major mobile OS platforms. If the big companies take this approach, it seems logical for us to follow suit.
Perhaps we should focus more on a general architecture that we should offer across platforms instead of an implementation that can be shared.
Would anyone advise us to make use of C/C++ to develop such a framework (shared library) for the mobile site of our webservices? If so, why?
It really depends on what level of customized code you want to have. I worked at a game company previously, and we made two games for both iPhone and Android, and at least 90% of the codebase was shared between the two platforms in c++ code. Sometimes it is significantly easier to implement elements with specialized third-party libraries, like for Facebook and the like, but maintaining that code means continually doing it for both platforms. That was one of the reasons why we even implemented our own UI objects in c++ for our games. Because even though the initial setup would have been easier to do with Interface Builder and Android's XMLs, the maintenance and tweaking necessary ended up being significantly less because we went with a shared codebase.
In short, I would highly recommend writing any shared customized code in C/C++, and things that are significantly easier in their native codebases (java for android, or obj-c for iphone) and you don't expect to change much, to keep separate.
Depending on which WS protocol you use it may be more or less hard to do, but anyway I see little advantage in doing that in C/C++ for a mobile platform.
If you were using SOAP, I'd never consider C/C++, even for a desktop app. I already used SOAP libraries for C++ and they are a lot harder to use than their Java/.net counterparts, and the way they are implemented (mapping SOAP objects to C structs) is very prone to crashes if the format changes. Not to mention that you have to recompile your client when the WSDL changes.
As I understood in your case you plan to use REST. I never found a good REST library for C/C++, but recently I did a desktop project in which I implemented a C++ REST client using simply WinHTTP (in Windows) and libCURL (in Linux). Of course, they provide just the HTTP part, so I had to add cppdom for XML parsing. If you use JSON, there are many good libs like jsoncpp, libjson.
I'd say to you that even in a desktop environment it was harder to do than would be in .net or java, and was only done this way because it was part of a larger application already written in C/C++.
Anyway, you'll have more work and not much advantage since all those modern mobile platforms provide rich libraries that do the same thing, and probably the user of your API will develop in the platform's main language, so you'll have the double extra work of implementing the WS access code AND the binding code. As I assume all (or at least most) of your logic is in your server, not the client, there's not much common code between the platforms to justify using C/C++.