Deep Linking

Opening specific sections of your app right from Marigold Messages

Deep linking is a powerful technique that, with some preparation by a developer, can lead to a very advanced form of messaging. Deep linking is a process by where a URL is opened by your app, and then in response your app is opened to a specific screen. You might be familiar with deep linking on Facebook, where URIs are in the form of fb://something. In deep links, the protocol is the name of your app (or similar) and your app defines the routes the URL maps to.

Marigold supports deep links with URL type messages. You can include your deep link URL (for your app scheme) in the URL field of a link message and it will trigger your deep links. However, if you want to use push messages only, then this is achieved instead with Key-Value Payloads.

iOS

On iOS deep linking occurs with Custom URL Schemes. There are 3 main parts to this.

  1. Define your URL Scheme in you app's Info.plist
  2. Implement -application:openURL:options: in your app delegate
  3. Inside this, parse the URL for any parameters, initialize the correct view controllers and present them.

For implementation details on Custom URL Schemes, have a look in the iOS Developer Library on Apple's website.

Here's an example using a simple url scheme: myapp://?screen=new_post.

//In your App Delegate
	- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options {
		NSDictionary *params = [self queryParamsFromURL:url];
	    if ([[params objectForKey:@"screens"] isEqualToString:@"new_post"]) {
	    	NewPostViewController *npViewController = [NewPostViewController alloc] init];
	    	[self.window.rootViewController presentViewController:npViewController];
		} // else if other supported views, keys and values here
		return YES;
}

- (NSDictionary *)queryParamsFromURL:(NSURL *)url {
	    NSArray *queryComponents = [[url query] componentsSeparatedByString:@"&"];
	    
	    NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithCapacity:[queryComponents count]];
	    
	    for (NSString *queryComponent in queryComponents) {
	        NSArray *paramComponents = [queryComponent componentsSeparatedByString:@"="];
	        
	        id object = nil;
	        
	        if ([paramComponents count] > 1) {
	            object = [paramComponents[1] stringByRemovingPercentEncoding];
	        }
	        else {
	            object = [NSNull null];
	        }
	        
	        NSString *key = [paramComponents[0] stringByRemovingPercentEncoding];
	        
	        [parameters setObject:object forKey:key];
	    }
	    
	    return parameters;
}
//In your App Delegate
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    let params = self.queryParams(url: url)
    let screens = params["screens"]
    if screens == "new_post" {
        let npViewController = NewPostViewController()
        self.window?.rootViewController?.present(npViewController, animated: true, completion: nil)
    }// else if other supported views, keys and values here
    return true
}

func queryParams(url: URL) -> Dictionary<String, String> {
    var parameters = Dictionary<String, String>()
    if let queryComponents = url.query?.components(separatedBy: "&") {
        for queryComponent in queryComponents {
            let paramComponents = queryComponent.components(separatedBy: "=")
            var object : String? = nil
            if paramComponents.count > 1 {
              	object = paramComponents[1]
            }
            let key = paramComponents[0]
            parameters[key] = object
        }
    }
    return parameters
}

Note: If the deep link comes from the Marigold Message Stream, you may want to dismiss the message stream before navigating to your desired view.

You will also need to add an addition field to your Info.plist that defines an array of schemes using the LSApplicationQueriesSchemes key.

Android

On Android, deep linking occurs with the use of Intent Filters. There are 3 main parts to this.

First, define your Intent Filter in your app's manifest file, with the <data> element filled out. This must be associated with an activity, typically the root.

<activity android:name=".MyActivity">
	<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="myapp"/>
	</intent-filter>
</activity>

Then, read the Intent that was used to start your application in the onCreate method of your activity. If your application is already running, the Intent will be sent to the onNewIntent(Intent) method of the receiving Activity.

Intent intent = getIntent();
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
    Uri uri = intent.getData();
    String valueOne = uri.getQueryParameter("keyOne");
    String valueTwo = uri.getQueryParameter("keyTwo");
}
val intent = intent
if (Intent.ACTION_VIEW == intent.action) {
    val uri: Uri = intent.data
    val valueOne: String = uri.getQueryParameter("keyOne")
    val valueTwo: String = uri.getQueryParameter("keyTwo")
}

Finally, inside this, parse the URL for any parameters, configure your activity respectively.

For implementation details on Intent Filters, have a look in the Android Developer Library on Google's website.

Triggering with Marigold

Once implemented by a developer, deep linking URLs can be sent like any other link message. Simply send the link to your audience, and once the user taps on the link, they'll be directed to the correct part of the app.

If you want to use deep linking without messages (just using a plain push), then this can be achieved with Key-Value Payloads.