├── README.md
└── assets
└── exone.png
/README.md:
--------------------------------------------------------------------------------
1 | # Universal Linking For React-Native with Rails API, and Deep Linking Android
2 | Just a tutorial on how to set up Universal Linking for iOS with a Rails server, and Deep Linking on an Android device.
3 |
4 | ## iOS
5 | - Universal Linking allows users to click on a link from a text message or email and your app will `magically` launch
6 |
7 | - You can pass information in the url of link so your app can launch to a specific screen and fetch the proper data
8 |
9 | - The documentation from Apple is not the best, I will explain in extreme detail how to accomplish this with `React-Native` and a `Rails` server
10 |
11 | ### Requirements
12 |
13 | 1. You have to set up your server
14 | 2. Your server must use HTTPS or else the set-up sucks and and these instructions will not work for you
15 | 2. 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.
16 | 3. You have to have a developer account with iTunes to test on your device
17 | 4. You have to configure your app to handle the link/parse it for pertinent information.
18 |
19 | #### 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 :)
20 |
21 | ### Server Configuration
22 |
23 | 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.
24 |
25 |
26 | #### Your link should go to a valid web page.
27 |
28 | - for instance the link `https://brewcards.herokuapp.com/bars/1` goes 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 the `1` from the url and re-direct the user to the proper app screen and fetch data.
29 |
30 |
31 | #### 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*
32 |
33 | - Rails example `get '/apple-app-site-association' => 'whatever#whatever_method'`
34 |
35 |
36 | #### When a request is made to that path, you must return the proper file with the proper configuration.
37 | - Apple docs do a great job explaining this file configuration. Click here to see how to structure your file
38 |
39 | #### Apple says the the file has to have a certain name and certain location.
40 | - 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-association` url and there is no extension on the file. It may be JSON format, just don't put .anything as the extension
41 |
42 | - In Rails, I put the file in the `public` directory
43 |
44 |
45 | ## My controller in Rails
46 |
47 |
48 | ```ruby
49 |
50 | class WhateverController < ApplicationController
51 |
52 | def whatever_method
53 | send_file "#{Rails.root}/public/whatever_I_named_my_apple_association_file_with_no_extension", {:type => "application/json"}
54 | end
55 |
56 | end
57 |
58 | ```
59 |
60 | # Server Configuration Done
61 |
62 | # App Configuration
63 |
64 | 1. In X-Code turn on Associated Domains
65 | 2. Add your domain.
66 | 3. Make sure to prefix the domain with `applinks:` in place of `https://`
67 |
68 | 
69 |
70 | ### Add RCTLinking to your project
71 | Do what is says in the link about. **Make sure to add the library to the header search path as recursive**
72 |
73 |
74 | ### Modify App Delegate
75 |
76 | ```objc
77 | #import "RCTLinkingManager.h" // import
78 |
79 | // ADD THIS METHOD
80 |
81 | - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
82 | restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
83 | {
84 | return [RCTLinkingManager application:application
85 | continueUserActivity:userActivity
86 | restorationHandler:restorationHandler];
87 | }
88 |
89 |
90 | ```
91 |
92 | ### Handle the links in your app.
93 |
94 | - There are two scenarios you must account for.
95 | 1. Your app is closed and gets opened via the `Universal Linking` we have enabled or `Deep Linking Android`
96 | 2. Your app is running in the background and is `woke up` from the `Universal Linking` or `Deep Linking`
97 |
98 | In your app's Navigator, add some methods to handle the Universal Linking.
99 |
100 | ```js
101 |
102 | componentDidMount(){
103 | // this handles the case where the app is closed and is launched via Universal Linking.
104 | Linking.getInitialURL()
105 | .then((url) => {
106 | if (url) {
107 | // Alert.alert('GET INIT URL','initial url ' + url)
108 | this.resetStackToProperRoute(url)
109 | }
110 | })
111 | .catch((e) => {})
112 |
113 | // This listener handles the case where the app is woken up from the Universal or Deep Linking
114 | Linking.addEventListener('url', this.appWokeUp);
115 | }
116 |
117 | componentWillUnmount(){
118 | // Remove the listener
119 | Linking.removeEventListener('url', this.appWokeUp);
120 | }
121 |
122 | appWokeUp = (event) => {
123 | // this handles the use case where the app is running in the background and is activated by the listener...
124 | // Alert.alert('Linking Listener','url ' + event.url)
125 | this.resetStackToProperRoute(event.url)
126 | }
127 |
128 | resetStackToProperRoute = (url) => {
129 | // grab the trailing portion of the url so we can use that data to fetch proper information from the server
130 | let trailing = url.slice(url.lastIndexOf('/') + 1,url.length)
131 | // reset the stack, let your properly coded application handle everything and populate everthing.
132 | this.props.resetStack([ BarsMain, { ...BarDetail, id:parseInt(trailing) } ])
133 | }
134 | ```
135 |
136 |
137 | # Universal Linking....Boom.
138 |
139 | # Android
140 |
141 | Android is a little easier...no server configuration
142 |
143 | 1. Add an `` to you `AndroidManifest.xml`
144 | 2. Describe what url scheme you want handled.
145 | 3. Profit?
146 |
147 | ```xml
148 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
172 |
173 |
174 |
175 | ```
176 |
177 | The `` attribute is the important stuff. It defines what url schemes to intercept read about it here
178 |
179 | # Deep Linking...Boom.
180 |
--------------------------------------------------------------------------------
/assets/exone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/parkerdan/React-Native-Rails-Universal-Linking/2a4cdb0ae9a318d468a7b7ae0915e13abfbdf1b1/assets/exone.png
--------------------------------------------------------------------------------