React Native URL Scheme and Linking API

React Native is possible the best hybrid framework for building mobile app at the moment. Not just its performance but also the development experience it provides. If you build it well, one really can’t tell if your app is native or a hybrid.

I spent my last 3 month developing a complicated hybrid app using react native. It involves many network requests, forms, lists, etc. It was undoubtedly challenging, but the result was quite satisfying.

For my next project, I was given another chance to work with React Native. This time I need to build a “AppStore” kind of application, which allow the user to install apps and launch installed apps right from this custom “AppStore”.

To launch other Apps in iOS or Android, we must register custom URL Schemes in the Apps we wish to launch.

Register URL Schemes

iOS

On iOS, we need to add a key CFBundleURLTYpes to the Info.plist file within the Xcode project.

Under this key we add an array, and define 2 keys CFBundleURLName and CFBundleURLSchemes.

Under CFBundleURLName you need to add a unique string that identifies your bundle, I used the same string as my app’s bundle identifier and it worked fine. Under CFBundleURLSchemes you need to add another array, and put in your desired URL schemes.

Here is an example of such entry inside Info.plist:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.johnsonsu.example</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>johnsonsu-example</string>
        </array>
    </dict>
</array>

More info about iOS URL Scheme can be found on the official documentation.

Android

Android’s setup is similar to iOS. We need to add a custom intent-filter in the Android app’s AndroidManifest.xml file.

Here is an example of such intent-filter:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <data android:scheme="johnsonsu-example"/>
</intent-filter>

Since React Native’s Linking API will be creating an intent with action equals to android.intent.action.VIEW, your intent-filter must contain an action tag with this name.

The data tag is where you should define your custom URL Scheme. In this example I used the same one as the iOS scheme. Doing it this way allows me to use the exact same code in React Native to launch these applications in both iOS and Android.

More info about Android Intent Filter can be found on the official documentation.

Launching the App in React Native

If you setup your apps properly, you should be able to launch that app in React Native using:

import { Linking } from 'react-native';

Linking.openURL('johnsonsu-example://').catch(err => console.error('An error occurred', err));

If the OS can’t handle the URL you tried to open, the exception will be caught inside the catch block, and you should handle it properly to prevent a crash.

A safer way to open URL is to check if the OS can handle it before you open it. You can check it using:

import { Linking } from 'react-native';

const url = 'johnsonsu-example://';
Linking.canOpenURL(url).then(supported => {
  if (!supported) {
    console.log('Can\'t handle url: ' + url);
  } else {
    return Linking.openURL(url);
  }
}).catch(err => console.error('An error occurred', err));

This works on Android without any setup. However, on iOS 9 or above, you need to add LSApplicationQueriesSchemes to your React Native app’s Info.plist or Linking.canOpenURL(url) will always returns false.

This is an example entry in Info.plist:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>johnsonsu-example</string>
    <string>youtube</string>
    <string>facebook</string>
</array>

There you have it, a simple way to launch any other apps from your React Native app!

4 Comments

Add yours →

  1. Hi, thank you for this great article. It worked like a charm. However in my case I also want to pass some text while transitioning between apps. Would you mind helping me out about how to do this?

  2. I just wodering how to open android system setting by react native.
    I don’t know the schema of android system setting , such as “com.android.settings”.

Leave a Reply

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