ReactNative Native Modules in Swift – Part 1 (Install ReactNative inside a Swift project…)

So I was working on a clean architecture example in Swift based on this post and the way I implement VIPR. I was adding/implementing a simplified version of it based on the graph represented in Fig-1.

Fig – 1 : VIPR Simplified in Swift

And then I decided to prove that this architecture is really decoupled and thus wanted to integrate a ReactNative View into it. Of course I was overestimated my knowledge of ReactNative because I did few small projects in ReactNative and it looked very easy (because I was not bridging to native modules…).

So I started to follow this tutorial from Facebook which is really nicely done : Integration With existing Apps. Well, it’s very good, except that it describes how to generate a RCTRootView, bind it to a UIViewController and present this UIViewController on the app. That’s a first step but not enough to generate a bridge with a native module.

First, let’s integrate ReactNative with a Swift project. Here are the steps to follow :

  1. create an folder and inside this folder create a /ios folder
  2. create a file named “package.json” and inside it copy and paste this :
    	{
    	  "name": "MyReactNativeApp",
    	  "version": "0.0.1",
    	  "private": true,
    	  "scripts": {
    	    "start": "node node_modules/react-native/local-cli/cli.js start"
    	  }
    	}
    

    where “MyReactNativeApp” is the name of your app and version is the version number (here 0.0.1).

  3. Then we need to install React and React native. You will use npm (Node Package Manager) :
    npm install --save react-native@0.51.0
  4. this will indicate you if your React package is up to date which is probably not the case.
    Shell

    Look at this instruction : “react-native@0.51.0 requires a peer of react@16.0.0 but none is installed. You must install peer dependencies yourself

  5. Check the version number of react that is required (here : 16.0.0) and execute this :
    npm install --save react@16.0.0

Now you should see a newly created /node-modules folder and a package-lock.json (all React boilerplate is in here).

folder structure
  1. inside the /ios folder, create an iOS project with XCode named MyReactNativeApp. Of course this project is in Swift (we could use ObjC and then integrate Swift but that’s another topic that I will not cover here).
    create iOS project

    By default, XCode will create a folder inside the iOS folder. Rename this folder to any name, extract the content of this folder to the root of the /ios folder and then delete the renamed folder (we could keep it but then React will need some configuration that I don’t want to talk about here).

    ios floder before renaming

    ios folder after renaming
  2. Install Cocoapods on your computer (here)
  3. go to your /ios folder and create a podfile (a file named podfile) with this inside :
     
    use_frameworks!
    platform :ios, '11.0'
    
    target 'MyReactNativeApp' do
      pod 'React', :path => '../node_modules/react-native', :subspecs => [
        'Core',
        'CxxBridge', # Include this for RN >= 0.47
        'DevSupport', # Include this to enable In-App Devmenu if RN >= 0.43
        'RCTText',
        'RCTNetwork',
        'RCTWebSocket', # needed for debugging
        # Add any other subspecs you want to use in your project
      ]
      # Explicitly include Yoga if you are using RN >= 0.42.0
      pod "yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
    
      # Third party deps podspec link
      pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
      pod 'GLog', :podspec => '../node_modules/react-native/third-party-podspecs/GLog.podspec'
      pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
      pod 'Alamofire'
    end
    
    post_install do |installer|
        installer.pods_project.targets.each do |target|
            if target.name == 'yoga'
                target.build_configurations.each do |config|
                    config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'NO'
                    config.build_settings['GCC_WARN_64_TO_32_BIT_CONVERSION'] = 'NO'
                end
            end
        end
    end
    

    In here, I’m also installing AlamoFire just for the test. It’s not needed in your case but it shows you where you could add any new pod for your project. The last lines enable you to avoid errors when yoga is going to be compiled as some warning can be treated as errors.

  4. go back to your terminal and execute a pod installation inside the /ios folder :
    pod install

Once done you should see this :

pod installation complete

If your project was opened in XCode, just close it and open the XCWorkspace that was created by Cocoapods instead.

ios folder after pod installation complete.

Run “Command+B” and it should fail – at least with ReactNative 0.51.0 – because “‘fishhook/fishhook.h’ file not found” (see screen capture).

First compilation fails because of bad import.

Fix this by changing <fishhook/fishhook.h> to <React/fishhook.h> and recompile (“Command+B”). This time it should work properly. I’m pretty sure this will be fixed in the next releases of ReactNative and in our case it’s quite ok as React is integrated as a development pod so if you upgrade ReactNative next time then you should get a correct version free of compile errors.
(Also don’t pay attention to warnings, I know it’s not a good practice to have warnings when you compile and there are solutions to shut them inside your podfile but this is not the subject of this post :-))

Working after fixing. 🙂

So now, we have an iOS native project that integrates ReactNative, so let’s create a ReactNative View and make it communicate with a native module. To be able to make this we need to understand how ReactNative interacts with it’s native environnement (iOS in our case).

If you are here, then you can go to Part 2 : here.
All the files can be found on github :
https://github.com/fredfoc/ReactNativePart1and2

 

 

2 thoughts on “ReactNative Native Modules in Swift – Part 1 (Install ReactNative inside a Swift project…)”

Leave a Reply

Your email address will not be published. Required fields are marked *