Last active
January 19, 2022 02:55
-
-
Save EddyVerbruggen/cf713b9f860119913364b06d880f5b25 to your computer and use it in GitHub Desktop.
App links on iOS and Android with NativeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Add this to your <activity>, so any link (clicked in fi. an e-mail) | |
will open your app instead of the website, but only if it matches these whitelisted path patterns | |
*/ | |
<activity android:launchMode="singleInstance"><!-- set the launchMode property to this value! --> | |
<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" android:host="*.mywebsite.com" android:pathPattern="/action_planner"/> | |
<data android:scheme="https" android:host="*.mywebsite.com" android:pathPattern="/.*/action_planner"/> | |
</intent-filter> | |
</activity> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
You'll need to 'require' the previous file and set it as the AppDelegate like so: | |
*/ | |
import * as application from "tns-core-modules/application"; | |
if (application.ios) { | |
application.ios.delegate = require("./ios-app-delegate-extensions").IOSAppDelegateExtensions; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
For iOS you need to create a file 'apple-app-site-association' and save it to the root of the https(!) website | |
you want to steal links off. The file needs to be served as json, much like this example: https://app.mydailylifestyle.com/apple-app-site-association | |
Note that 'YAZ6LJG875' below is the team id or app id. | |
*/ | |
{ | |
"applinks": { | |
"apps": [], | |
"details": [ | |
{ | |
"appID": "YAZ6LJG871.com.your.PackageName", | |
"paths": [ | |
"/action_planner", | |
"/*/action_planner" | |
] | |
}, | |
{ | |
"appID": "YAZ6LJG871.com.your.OtherPackageName", | |
"paths": [ | |
"/action_planner", | |
"/*/action_planner" | |
] | |
} | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Add this file to yout /app folder. | |
*/ | |
import { NSAppService } from "~/mobile/core"; | |
export class IOSAppDelegateExtensions extends UIResponder implements UIApplicationDelegate { | |
//noinspection JSUnusedGlobalSymbols | |
public static ObjCProtocols = [UIApplicationDelegate]; | |
private static _callback: Function = null; | |
public static setCallback(callback?: Function) { | |
this._callback = callback; | |
} | |
// iOS >= 9.1 | |
public applicationContinueUserActivityRestorationHandler(application: UIApplication, userActivity: NSUserActivity, restorationHandler: (p1: NSArray<any>) => void): boolean { | |
if (userActivity.webpageURL) { | |
console.log("applicationContinueUserActivityRestorationHandler, userActivity.webpageURL: " + userActivity.webpageURL); | |
// save the url somewhere - I'm simply using a static property in some class. | |
NSAppService.openAppFromWebUri = userActivity.webpageURL.absoluteString; | |
return true; | |
} | |
return false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
While bootstrapping you app, you can see if that delegate method set the 'NSAppService.openAppFromWebUri' property. | |
Note that this structure really depends on what your app looks like. For instance, you could throw this code in the | |
constructor of app.module.ts | |
*/ | |
import * as nsApp from "tns-core-modules/application"; | |
nsApp.on(nsApp.resumeEvent, (eventData: nsApp.ApplicationEventData) => { | |
// on cold boot, this runs before the delegate method which sets NSAppService.openAppFromWebUri, so using a timeout | |
setTimeout(() => { | |
if (NSAppService.openAppFromWebUri) { | |
// This is app-specific code, where I'm checking a user profile for permissions and logged-in state. | |
const profile: Profile = storage.getItem(StorageKey.PROFILE); | |
if (profile === null) { | |
// not logged in, so let's handle the link after login | |
// Note that the after-login code is not included in this Gist, but it simply calls 'handleUniversalLink' after a little timeout. | |
return; | |
} | |
handleUniversalLink(this.routerExtensions, profile); | |
} | |
}, 100); // This is suboptimal.. better use a native event, but didn't bother to find one yet as it seems to work just fine | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Add a file that actually handles the incoming link (called from ns-app.service.ts). | |
*/ | |
import { NSAppService } from "~/mobile/core"; | |
import { RouterExtensions } from "~/modules/core/services/router-extensions.service"; | |
import { Profile } from "~/modules/sample/model/Profile"; | |
export function handleUniversalLink(routerExtensions: RouterExtensions, profile: Profile): void { | |
// grab the cached url | |
const weburi = NSAppService.openAppFromWebUri.toLowerCase(); | |
// and set it to undefined, so it doesn't deeplink us again | |
NSAppService.openAppFromWebUri = undefined; | |
// let's see where we need to go, based on that link - default "home". | |
let requestedRoute = "/home"; | |
if (weburi.indexOf("/exercises") > -1 && profile.features.indexOf("exercise") > -1) { | |
requestedRoute = "/exercise"; | |
} else if (weburi.indexOf("/survey/") > -1) { | |
const slug = weburi.substr(weburi.lastIndexOf("/")); | |
requestedRoute = "/questionnaire" + slug; | |
} else if (weburi.indexOf("/page/bibliotheek") > -1 && profile.features.indexOf("library") > -1) { | |
requestedRoute = "/documents"; | |
} else if (weburi.indexOf("/measurements") > -1 && profile.features.indexOf("enter_weight") > -1) { | |
requestedRoute = "/weightentry"; | |
} | |
if (requestedRoute === routerExtensions.router.url) { | |
// we're already where we want to be, so skip the rest | |
return; | |
} | |
// route the user to the requested page (note that this is pseudo-code as the actual code in our app is a bit more complex) | |
routerExtensions.navigate([requestedRoute]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment