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.
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)
}