React-Native-Rails-Universal-Linking
React-Native-Rails-Universal-Linking copied to clipboard
React-Native Universal Linking tutorial with Rails example
Universal Linking For React-Native with Rails API, and Deep Linking Android
Just a tutorial on how to set up Universal Linking for iOS with a Rails server, and Deep Linking on an Android device.
iOS
-
Universal Linking allows users to click on a link from a text message or email and your app will
magicallylaunch -
You can pass information in the url of link so your app can launch to a specific screen and fetch the proper data
-
The documentation from Apple is not the best, I will explain in extreme detail how to accomplish this with
React-Nativeand aRailsserver
Requirements
- You have to set up your server
- Your server must use HTTPS or else the set-up sucks and and these instructions will not work for you
- The links you provide to users should go to a valid web page should they not have the app installed. It's a fallback and good UX.
- You have to have a developer account with iTunes to test on your device
- You have to configure your app to handle the link/parse it for pertinent information.
Universal Linking does not support iOS < 9. You want to support old versions of iOS, great...good for you. I hope you support old versions of IE as well... I do not support these old things. I also think everyone should always use flex-box...always...no exceptions :)
Server Configuration
This is where the Apple doc's didn't really help that much. I use Rails servers and the set-up instructions weren't the best for my use case.
#### Your link should go to a valid web page.
- for instance the link
https://brewcards.herokuapp.com/bars/1goes to a web page. Should the user click the link and the app is not installed, then Safari will open to a web page. In this example I am going to extract the1from the url and re-direct the user to the proper app screen and fetch data.
Your server has to have a route that is defined as a get with the path /apple-app-site-association you can not change this name
- Rails example
get '/apple-app-site-association' => 'whatever#whatever_method'
When a request is made to that path, you must return the proper file with the proper configuration.
Apple says the the file has to have a certain name and certain location.
-
This is not true. You can name the file whatever the eff you want as long as you return it when the request is made to the
apple-app-site-associationurl and there is no extension on the file. It may be JSON format, just don't put .anything as the extension -
In Rails, I put the file in the
publicdirectory
My controller in Rails
class WhateverController < ApplicationController
def whatever_method
send_file "#{Rails.root}/public/whatever_I_named_my_apple_association_file_with_no_extension", {:type => "application/json"}
end
end
Server Configuration Done
App Configuration
- In X-Code turn on Associated Domains
- Add your domain.
- Make sure to prefix the domain with
applinks:in place ofhttps://

Add RCTLinking to your project
Do what is says in the link about. Make sure to add the library to the header search path as recursive
Modify App Delegate
#import "RCTLinkingManager.h" // import
// ADD THIS METHOD
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
Handle the links in your app.
- There are two scenarios you must account for.
- Your app is closed and gets opened via the
Universal Linkingwe have enabled orDeep Linking Android - Your app is running in the background and is
woke upfrom theUniversal LinkingorDeep Linking
In your app's Navigator, add some methods to handle the Universal Linking.
componentDidMount(){
// this handles the case where the app is closed and is launched via Universal Linking.
Linking.getInitialURL()
.then((url) => {
if (url) {
// Alert.alert('GET INIT URL','initial url ' + url)
this.resetStackToProperRoute(url)
}
})
.catch((e) => {})
// This listener handles the case where the app is woken up from the Universal or Deep Linking
Linking.addEventListener('url', this.appWokeUp);
}
componentWillUnmount(){
// Remove the listener
Linking.removeEventListener('url', this.appWokeUp);
}
appWokeUp = (event) => {
// this handles the use case where the app is running in the background and is activated by the listener...
// Alert.alert('Linking Listener','url ' + event.url)
this.resetStackToProperRoute(event.url)
}
resetStackToProperRoute = (url) => {
// grab the trailing portion of the url so we can use that data to fetch proper information from the server
let trailing = url.slice(url.lastIndexOf('/') + 1,url.length)
// reset the stack, let your properly coded application handle everything and populate everthing.
this.props.resetStack([ BarsMain, { ...BarDetail, id:parseInt(trailing) } ])
}
Universal Linking....Boom.
Android
Android is a little easier...no server configuration
- Add an
<intent-filter>to youAndroidManifest.xml - Describe what url scheme you want handled.
- Profit?
<!-- Add an Intent filter withing your
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
...rest of stuffs
....the intent filter below...
</activity>
-->
<!-- This is how you structure your Intent filter -->
<intent-filter>
<!-- This is just configuration -->
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- This is the important stuff. Link to Android docs below -->
<data android:scheme="https"
android:host="brewcards.herokuapp.com"
android:pathPrefix="/bars" />
</intent-filter>