React-Native Universal Linking iOS, Deep Linking Android with a Rails Server
Universal Linking and Deep Linking allow your app to launch from a link within an email or text message, if your app is installed on the users device
- You can pass information in the url of link so your app can launch to a specific screen and fetch the proper data.
- Set up is fairly easy with a Rails server using HTTPS, and if you only support iOS 9+.
- If you want to support iOS versions less than 9, or use HTTP…this isn’t for you…
Requirements
- Access to server.
- Developer account with Apple/Google Play.
- Links that actually go to a webpage should the user not have the app installed…it’s just good UX.
Rails 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 server must have a route with a get method at the path apple-app-site-association. Rails Example:
get '/apple-app-site-association' => 'whatever#whatever_method'
When a request is made to that url, you must return a file with the proper configuration. Apple docs do a great job of explaining this.
- Apple Docs say the file has to have a certain name and location…this is not true.
- You can name the file whatever you want as long as you return it when a request is made to the above URL.
- Do not put an extension on the file.
- Do not put an extension on the file.
- Put the file in the public directory…
Rails Controller
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…time to play with X-Code
- 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:
1: Your app is closed and gets opened via the Universal Linking
or Deep Linking Android
.
2: Your app is running in the background and is woken up from the Universal Linking
or Deep Linking
.
In your app’s Top-Most Navigator, add some methods to handle the Links.
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) => {
// Do Whatever you need to do within your app to redirect users to the proper route
}
Android Set-Up
Android is a pretty easy set-up in comparison to iOS, only three steps…
1: Add an <intent-filter>
to you AndroidManifest.xml
2: Describe what url scheme you want handled.
3: Profit??
<!-- Add an Intent filter within 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>
The <data />
attribute is the important stuff. It defines what url schemes to intercept read about it here