When React Native for Android came out I was excited to investigate it more at one of Liips monthly innovation days. Liip already developed a React Native app for iOS and we wanted to know how it works for Android. We were: Andrey, Germain, Lukasz and me. Germain is currently working on a cross platform app written with Xamarin.
For this hackday we tried to port an existing React Native iOS app to Android.
TL;DR: We are waiting for WebViews to be supported. See the pull request for changes. We didn't need to dive deep into Android APIs like XML Layouts for views.
How code sharing works
React Native has a “packer” which is responsible for collecting and loading all javascript files and resources. To avoid explicitly checking for the current platforms using _if/else _blocks, the packer ignores all files which end in .android.js on iOS and all files ending in .ios.js on Android. The way to develop platform specific components is: First divide the app into small components, each component in its own file. Then implement a platform specific version of a component that works differently.
For example we have a ProgressCircle component which displays a progress in a circle. On iOS we implemented this using React ART but at the moment there is no support for Android. Fortunately we found a package which provided what we needed to get it to work on Anroid. So now have next to the existing ProgessCircle.js file a new ProgressCircle.android.js file. We didn't have to change the existing code.An idea was to use inheritance with ES6 classes to not redefine properties etc. We didn't explore this idea further yet.
What we needed to change
For navigating between screens on Android we introduced the Navigator component. We used the existing route definition we used for the iOS navigator and fed it into the Navigator component. That went quite well, only a few lines of code were needed to make the navigation work on Android. Binding the back button we stole from the HackerNews React Native app. On iOS we still use the NavigatorIOS to keep the native look and feel.Since we used the ActivityIndicatorIOS directly which only works on iOS, we had to create a new component “LoadingIndicator” which uses a ProgressBarAndroid on Android and the ActivityIndicatorIOS on iOS.
Like described above we also needed to add an implementation for the ProgressCircle component on Android.
What is not working
Our main issue was that WebViews are not yet supported on Android. We currently use WebViews for authentication on a website. Unless we find another solution to do this, we will wait for Facebook's implementation which should arrive soon.
Another topic worth to mention is the app states lifecycle. During our tests we couldn't find a way to interact with these events on android, although it exists for iOS. Hopefully Android will come along in a coming release.
Translations (new feature added to our app)
To test out a feature which was not easy to implement with Xamarin, we looked at translations. For that we found a package which works on Android and iOS. We translated a few buttons as an example and it works well on both platforms. The device language is automatically detected, in the screenshot you see the french version.All changes are in our pull request.
Summary
The idea of React Native is to learn once how to write React components and use this knowledge on different platforms. Knowing the APIs of those platforms becomes less important. For this first effort we didn't have to dive into Android APIs at all.
React Native for Android has potential, but we are missing some features like WebViews and ART which will come with time. In a few month from now we expect the Android version to have caught up to the iOS version.