I’m sure you’ve probably heard by now, React Native is awesome!

I’ve been interested in mobile app development for a while, but until now, I really just haven’t had time to dive in. A few months ago I started learning Swift, but got busy with some other projects and had to put it down. Recently, the hype around the inter-webs has been React, and I’ve had a chance to work on a few React projects. React has been a pleasure to work with, so when Facebook released React Native, I was pretty stoked. For someone like me who spends most of his days in JavaScript, and other ‘web’ languages, the ability to write native apps in JavaScript is pretty damn exciting.

The core of React Native contains a TON of what you need to build a pretty awesome app. However, from time to time, we’ll likely need to write our own custom component, re-use some Swift code we’ve used in the past, or take advantage of some platform specific API that isn’t available in the core. The React Native team has done a fantastic job of making this possible via the RCTBridgeModule (or React Native bridge). When React Native was first released, this could only be accomplished using Objective-C. I admit, I’m not a huge fan of Objective-C. I know it’s a great language, but coming from JavaScript, PHP, Ruby, etc…, the syntax is just so foreign feeling to me. I know I’d get it eventually, but Swift just ‘feels’ so much better. Thankfully, the ability to export custom components in Swift has arrived. I did quite a bit of searching for examples, but really only found the documentation available on the React Native website, and a pretty great tutorial by Jay Garcia on building custom components in Objective-C.

Armed with the manual and Jay’s tutorial, I decided to implement Jay’s MCFileWriterUtil in Swift and export to React Native!

A bit of a warning: I won’t be spending a ton of time delving into the code (which is all pretty basic stuff), or what is going on. This is more of a proof of concept. I would HIGHLY recommend you read Jay’s tutorial. He has done a great job explaining things. This tutorial will mostly touch on the differences and problems I ran into. If you have any questions, or would like further explanations, please hit me up in the comments. Also, I am NOT a Swift, Objective-C or React Native ninja. If I am doing something wrong, or not using best practices, please let me know in the comments and I’ll update things accordingly.

All of the code that will be used in this post is available on GitHub, so you may want to grab it before reading on. Most of the code (and code comments) come directly from Jay’s tutorial. I’ve tried to keep it as close as possible so that it’s easy to compare the two.

Missing Documentation?

This may be something that most Swift developers would have known, but is definitely not covered in the React Native documentation: we need an Objective-C bridging file (CustomSwiftComponent-Bridging-Header.h) that imports RCTBridgeModule.h. If we don’t have that file, we’ll receive an error when trying to build our application complaining about the missing header file. If we add the header file, but don’t add the import statement, we receive a build error for our use of an undeclared type (RCTResponseSenderBlock). Now, this could be missing from the documentation because it is obvious to those familiar with Swift, or it may be something I am doing wrong in Xcode. Either way, it seems to be a necessity. I’ve opened an issue on React Native’s GitHub account. I will update this post if something changes, or I get clarification. Update: My issue above was closed, with this pull request that I submitted, adding documentation to the React Native website regarding bridging files.

Private Implementation File

This part of the process is pretty straight forward, but a bit more cumbersome than the Objective-C implementation. As you’ve probably already read in the docs, or seen in Jay’s implementation, this file is where all the magic happens when implementing a custom Objective-C module. However, in the Swift implementation, because there is no support for macros, we expose our methods (that are built in our Swift file below) to the React Native bridge here, but we don’t include any of the logic here.

Swift

This file is obviously where the majority of the differences are between my implementation and Jay’s implementation, and for a pretty obvious reason: his is in Objective-C and mine is in Swift. Again, I’m not going to hit on all the syntax differences, but if you compare the two implementations, they’re pretty easy to spot. If you have questions, or see ways that I can make this better, please let me know in the comments. Again, this is one of my first few forays into Swift, so I won’t be offended!

React

This file is pretty much identical to Jay’s file, right down to most of the comments. There are a few comments that are mine, indicated by my initials, that explain things I changed and why. I wanted to keep things as close to the way Jay did it as possible so that we are comparing apples to apples.