Skip to content

Deep Links⚓︎

Both Android and iOS support deep links (also called App Links and Universal Links) to the app in the form of an HTTPS URL, which will open your app and start a session (e.g., for enroment or login).

Tip

If you have both an Android and iOS app and want this link to be the same for both platforms, it is important to chose a (sub)domain which is different from your public facing websites'. This is because on iOS, when a user visits your website using Safari, Safari will load all links (including universal ones) that belong to the same domain.

Info

You can create deep links for both login and enrol purposes, the Mobile SDK will differentiate between these and act accordingly. See here on how to construct deep links.

Deep link example

Deep link example

Add the pathPrefix to the app's configuration file using the universalLinkPathPrefix parameter. This allows to the Mobile SDK to correctly process the incoming URL.

Warning

Make sure that pathPrefix starts with a forward slash.

Android⚓︎

You need to configure the app to be able to handle deep/app links to your chosen (sub)domain in the AndroidManifest:

<activity android:name=”Activity”>
    <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="https" />
        <data android:host="(sub)domain" />
        <data android:pathPrefix="/prefix" />
    </intent-filter>
</activity>

Recommended

Add a verification file assetlinks.json to the .well-known directory of your chosen (sub)domain, see instructions here. Also configure the app to verify the (sub)domain for the app links:

<intent-filter android:autoVerify="true">

Then, add the following code in the Activity as specified in the AndroidManifest:

@Override
protected void onResume() {
super.onResume();
    //intents
    processIntents();
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    //now getIntent() should always return the last received intent
}

private void processIntents() {
    Intent intent = getIntent();
    if (intent == null) {
        return;
    }
    //process incoming intent (launch activity) to start client from other applications on the mobile phone
    if (intent.getData() != null) {
        NextAuth.getNextAuth().getSessionManager().start(intent.getData());
        //clean up intent
        intent.setData(null);
    }
}

iOS⚓︎

You need to associate your app with the chosen (sub)domain by adding a com.apple.developer.associated-domains entitlement to your app: see instructions here. Additionally, add a verification file apple-app-site-association to the .well-known directory of your chosen (sub)domain, see instructions here.

Verify your Universal Links

When the domains are live, collect a sysdiagnose on an iOS 13 device and inspect swcutil_show.txt to verify that the apple-app-site-association file was retrieved and parsed correctly. You can find additional information about collection a sysdiagnose here and some additional guidance on Universal Link debugging in the following blog post.

Make sure that apple-app-site-association is publicly available

Starting with iOS 14, apps no longer send requests for apple-app-site-association files directly to your web server. Instead, they send these requests to an Apple-managed content delivery network (CDN) dedicated to associated domains.

Apple’s CDN requests the apple-app-site-association file for your domain within 24 hours. Devices check for updates approximately once per week after app installation. This means that, if this file was not available when the CDN checks, iOS potentially cannot handle your deep links for about a week.

Once you've completed the above process, introduce the following method to your app's AppDelegate class. Note that we also pass the referring URL to the Mobile SDK, which will associate it with the session which is about to be started.

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    // MARK: - UIApplicationDelegate

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb else {
            return false
        }

        guard let webpageURL = userActivity.webpageURL else {
            return false
        }

        NextAuth.default.start(url: webpageURL, referrerURL: userActivity.referrerURL)
        return true
    }
}

Info

Note that the referrer URL will be exposed through its referrerURL property, enabling you to use the following the snippet to redirect the user back to their browser.

// MARK: - Observers

@objc func handleSessionUpdateNotification(_ notification: NSNotification) {
    guard let session = notification.object as? Session, session.isLoggedIn else {
        return
    }

    if let referrerURL = session.referrerURL {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            UIApplication.shared.open(referrerURL)
        }
    }
}

// MARK: - UIViewController

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(handleSessionUpdateNotification(_:)), name: NextAuth.NotificationNames.sessionUpdate, object: nil)
}