Deep Linking

You may set up a deep link for your preferred URL so that when users taps the defined URL from anywhere outside your app in their iOS device, they will be redirected to your app for a smoother experience.

There are 2 ways to implement deep linking in iOS: URL Scheme and Universal Links. The following image shows the pros and cons of both:

In this example, we will explain how to set up deep linking to open TapTalk.io's room list or a specific chat room page when user taps a specific link from their device.

You may choose to implement either one using the steps provided below.

Implementing URL Scheme

Step 1: Define a scheme to open your app

To start, choose a URL from your domain that will be used to open your app. In this example, we will try using taptalkio://.

You should use your own specified URL, the URL above is only meant as an example to make it easier to follow the guide.

Step 2: Add URL Types in project setting

Register your scheme in Xcode from the Info tab of your project settings.

  • In the URL Schemes box, specify the prefix you use for your URLs (taptalkio in this example)

  • Choose a role for your app: Editor: for URL schemes you define Viewer: for schemes your app adopts but doesn’t define

  • Specify your app identifier (Bundle ID)

iOS will recognize the URL Schemes as a link, you have to accommodate the URL format.

The url format will be ://(URL Schemes). To try it out, open the device's browser app and type ://taptalkio. Then permission to open the app will be shown.

Universal Links are standard web links (http://mydomain.com) that point to both a web page and a piece of content inside an app.

Step 1: Define a URL to open your app

To start, choose a URL from your domain that will be used to open your app. In this example, we will try using https://web.taptalk.io.

You should use your own specified URL, the URL above is only meant as an example to make it easier to follow the guide.

Step 2: Configure your app in Apple Developer Account to register approved domains

Register associated domain for your app in developer.apple.com. Open your developer account and click Identifiers in Certificates, IDs & Profiles.

Choose your project identifier and enable Associated Domains.

Step 3: Enable Associated Domain on in your Xcode project

In your app target, click + Capability icon and add Associated Domains.

Add your domain in Associated Domain section, prefixed with applinks: (for this example, applinks:www.taptalk.io)

Step 4: Create ‘apple-app-site-association’ file

The AASA (short for apple-app-site-association) is a file that lives on your website and associates your website domain with your native app. In other words, it’s a safe way to prove domain ownership to iOS.

The AASA file contains a JSON object with a list of apps and the URL paths on the domain that should be included or excluded as Universal Links. Here is a sample AASA file:

apple-app-site-association
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "YOURTEAMID.com.bundle.id",
                "paths": ["*"]
            }
        ]
}

The example below shows how to support multiple apps on the same domain

apple-app-site-association
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": “YOURTEAMID.com.firstapp.id",
                "paths": [ "NOT /e/*", "*", "/", "/first/*" ]
            },
            {
                "appID": “YOURTEAMID.com.secondapp.id",
                "paths": [ "NOT /e/*", "*", "/", "/second/*" ]
            }
        ]
}
  • appID : Built by combining your app’s Team ID (goto : https://developer.apple.com/account/#/membership/ to get the teamID) and the Bundle Identifier. In the example above, YOURTEAMID is the Team ID and com.bundle.id is the Bundle ID

  • paths : Array of strings that specify which paths are included or excluded from association. You can use NOT (before the path — as in the example JSON above) to disable paths. In this case, all the links on this path will go to the web instead of opening the app. You can use * as a wildcard to enable all paths in your entire website

  • Don’t append .json to the apple-app-site-association filename

Step 5: Host the AASA File on Your Domain

Once you are ready with your AASA file, you can now host it on your domain either at https://<<yourdomain>>/apple-app-site-association or https://<<yourdomain>>/.well-known/apple-app-site-association.

Upload the apple-app-site-association file to your HTTPS web server. You can place the file at the root of your server or in the .well-known subdirectory.

Important: iOS will only attempt to fetch the AASA file over a secure connection (HTTPS).

  • Is served over HTTPS.

  • Uses application/json MIME type.

  • Don’t append .json to the apple-app-site-association filename.

  • Has a size not exceeding 128 Kb (requirement in iOS 9.3.1 onwards).

When a user taps a universal link, iOS launches your app and sends it an NSUserActivity object that you can query to find out how your app was launched.

After you do all the above steps perfectly, when you click a universal link, the app will open up and the method application:continueUserActivity:restorationHandler will get called in AppDelegate.

The example code below will open a chat room if the roomID is specified in the tapped URL.

AppDelegate.m
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        // Obtain roomID from URL
        NSString *urlString = [userActivity.webpageURL absoluteString];
        NSString *roomID = [urlString stringByReplacingOccurrencesOfString:@"https://" withString:@""];
        roomID = [roomID stringByReplacingOccurrencesOfString:@"http://" withString:@""];
        roomID = [roomID stringByReplacingOccurrencesOfString:@"web.taptalk.io/" withString:@""];
        
        // Get & set activeRoom
        TAPRoomModel *activeRoom = [TAPChatManager sharedManager].activeRoom;
        NSString *activeRoomID;
        if (activeRoom != nil) {
            activeRoomID = activeRoom.roomID;
        }
        
        if (![roomID isEqualToString:@""]) {
            TAPRoomModel *room = [[TAPCoreChatRoomManager sharedManager] getLocalChatRoomData:roomID];
            
            if (room != nil && ![room.roomID isEqualToString:activeRoomID]) {
                // Local room data exists, open chat room
                [self openChatroomFromDeepLink:room];
            }
            else {
                // Fetch room data from server
                [[TAPCoreChatRoomManager sharedManager] getGroupChatRoomWithGroupRoomID:GROUP_ROOM_ID success:^(TAPRoomModel * _Nonnull room) {
                    if (room != nil && ![room.roomID isEqualToString:activeRoomID]) {
                        // Open chat room from obtained data
                        [self openChatroomFromDeepLink:room];
                    }
                } failure:^(NSError * _Nonnull error) {

                }];
            }
        }
    }
    
    return YES;
}

- (void)openChatroomFromDeepLink:(TAPRoomModel *)room {
    TAPUserModel *currentUser = [[TapTalk sharedInstance] getTapTalkActiveUser];
    if (currentUser == nil) {
        return;
    }
    BOOL isParticipant = NO;
    
    for (TAPUserModel *user in room.participants) {
        if ([user.userID isEqualToString:currentUser.userID]) {
            isParticipant = YES;
            break;
        }
    }
        
    if (isParticipant) {
        UINavigationController *latestActiveController = [[TapUI sharedInstance] getCurrentTapTalkActiveNavigationController];
        [[TapUI sharedInstance] createRoomWithRoom:room success:^(TapUIChatViewController * _Nonnull chatViewController) {
            chatViewController.hidesBottomBarWhenPushed = YES;
            [latestActiveController pushViewController:chatViewController animated:YES];
        }];
    }
}

You may begin testing by tapping your defined URL (e.g. https://web.taptalk.io/roomID) from email or notes app in your device.

Last updated