in Projects, Programming, Technology

React Native Notes

I just finished a one month React Native iOS project. The app was accepted into the app store yesterday – hooray! The app integrates Ustream live video with Firebase realtime chat and Braintree payments.

I chose React Native for a couple reasons.

1) The flex based layout system is a huge simplification (productivity and complexity) win over the native iOS contraint-based approach.

2) The simplicity of re-using our real-time javascript client code was really appealing.

Lastly, while prototyping I found it straightforward to make Javascript code interoperate with Swift and ObjectiveC. That gave me the confidence to proceed.

One of the first realizations I had was that I couldn’t actually re-use much of the code without changing it. There was copy and paste re-use, but our website didn’t have enough separation between component, model, and store. You obviously can’t re-use React component code designed for the web on the phone, but you can re-use the pattern, which counts for a lot.

The app got complex when I implemented deep linking from the web. The complexity came about when the UI state started to differ from the application (data) state. At that point, I had to implement “store” or “dispatcher” patterns. Data store classes load and cache data, and signal changes to the UI components via events (as opposed to the UI loading the data it needed when users tap).

Packaging app dependencies with React Native is awkward. There are several ways to do it, and package contributers have yet to standardized on a single method. Depending on the package, you may need to use npm, rnpm, cocoa pods, or manually drag code into the project. Experience with Objective-C and Swift projects (and C/C++ for that matter) was very useful here. If you were coming at this as a Javascript web developer, adding header and linker search paths would be confusing. Even adding fonts is a tricky three step process with xcode.

Some other notes: The react-native-device-info project needs to be updated so that it doesn’t depend on the React Native cocoa pod. I added this library to get at my app version number, and to access a unique ID for the device. Device info should be supported by React Native itself. As it stands, it device info project compatible with the latest version of React Native (due to the cocoa pod issue).

I didn’t quite make the leap (or implement it myself), but a library that supports percentage-based styles will be useful. In practice, hard coded view sizes were sufficient to work on all the devices we wanted to support. react-native-extended-stylesheet is one package that I considered adding but didn’t.

Also, I may look at trying either https://apphub.io or https://buddybuild.com for web-based app updates in the future.

The biggest snags I ran into were a babel conflict (conflicting .babelrc files) and verifying Google Analytics events (they were there, just very difficult to find until I created a separate property).

I’d like to spend another day building for Android. I’d like to learn Android deployment in order to be able to estimate the cost of Android projects.

Here are the packages I actually used for the project.

  •     babel-preset-react-native (for ES6)
  •     firebase (significantly, this is the Firebase Javascript SDK, not the iOS SDK)
  •     moment (date conversion)
  •     react-native-communications (for sending an email)
  •     react-native-facebook-login
  •     react-native-google-analytics
  •     react-native-linear-gradient (pretty backgrounds)
  •     react-native-orientation (for phone orientation changes)
  •     react-native-vector-icons (gives you access to 8 icon libraries)

Write a Comment

Comment

  1. Congrats on the app being accepted! What would you tell someone who’s unfamiliar with programming, but who has a couple great app ideas? What’s the best way and first step in getting started?

  2. Sam, I think everybody with an interest should try to learn to code. You might find it really fun (or you might find it very frustrating). I’d start with basics though, and expect to take a while learning. Of course, there are plenty of places to find and partner with freelance developers. That is probably the best way to realize your vision.

  3. I learned something from your article! Thanks for mentioning: react-native-extended-stylesheet! I used the following article to come up with a simple way of handling different screen sizes(though this doesn’t account for orientation change): https://medium.com/@elieslama/responsive-design-in-react-native-876ea9cd72a8#.vtrp0yc2b . My implementation in response to the article looks like the following:

    import Dimensions from ‘Dimensions’;
    const x = Dimensions.get(‘window’).width;
    const y = Dimensions.get(‘window’).height;
    const smallestDimension = x < y ? x : y;
    let ratio = (smallestDimension / 3.2) * 0.01;
    const base_unit = 16;
    const unit = base_unit * ratio;
    export function em(value) {
    return unit * value;
    }

    Basically 0.01 ratio per 3.2 dp units.

  4. Sam, there’s so much to learn. Just narrow down your idea and programming language and give it a try.

  5. Great blog post Adam! I didn’t even know about:
    – react-native-extended-stylesheet
    – react-native-orientation

    I’m now using both thanks to you!

    Here’s my dilemma though… how did you get uStream to work? Did you create a custom wrapper or leverage some webview bridge to interact with their web-only API?
    I’m trying to get jwPlayer to natively play in React Native, but for the life of me I can’t figure it out. I’m sure the solution to JWPlayer involves more or less what you did to make uStream work. Any guidance for this coding noob would be much appreciated.

  6. Thank you Adam… looking forward to that comment post containing that simple native wrapper for the uStream SDK!