Universal link not performing action despite url being hit - ios

I've successfully implemented universal links in to my app. The AASA is live on my website, and running the following command in my terminal successfully boots the app as expected:
xcrun simctl openurl booted https://websiteurl.com
Note - the url is different in practice.
For reference, this is my AASA structure:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "identifier.bundle_id",
"paths": ["*"]
}
]
}
}
However, my eventual aim with these universal links is to integrate it into an API which requires a redirect URI, where I send users back to the app.
As a result, I've created a ViewController, imaginatively called CallbackViewController. I will redirect users to this screen when the app is ready.
For now, I've introduced the following code into my AppDelegate file. The aim here is to print 'callback' when a universal link with the phrase 'callback' in is hit. However, when running the initial command in my terminal and adding /callback onto the end, nothing happens.
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL, let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
return false
}
if (components.path.contains("callback")) {
print("callback hit...")
}
return true
}
Does anyone know what I'm doing wrong in this function? I'm wondering if it's related to my AASA but unsure.
Thanks!

Related

iOS deeplinks not working when the app is completely closed [duplicate]

This question already has answers here:
iOS Deep link callbacks not working when the app is closed
(2 answers)
Application openURL gets called a few seconds after didFinishLaunchingWithOptions
(3 answers)
Closed 4 months ago.
In our app we have a deeplink that when tapped it opens the app to our homepage and then do a push to another section.
When the app is open in the background it works properly but when the app is completely closed it just opens the app, land in the homePage and it stays there.
In the AppDelegate we handle deeplinks in this way:
func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else { return false }
// Here we call a method to handle the deeplink and open the correct page
return true
}
Here is our json file for the deeplinks
{
"applinks": {
"apps": [],
"details": [
{
"appID": "appIdOne",
"paths": [
"*"
]
},
{
"appID": "appIdTwo",
"paths": [
"*"
]
},
{
"appID": "appIdThree",
"paths": [
"*"
]
}
]
}
}
Is there something missing?
Reading another answer to a similar question iOS Deep link callbacks not working when the app is closed
the issue may be that we don't have "content_available" : true field in our file. If it's the case where should we add that field?
Thanks in advance.
As suggested by Antanas I solved it by handling the deeplink management in application:didFinishLaunchingWithOptions: method which is called when the app opens. Instead when the app is completely closed application: UIApplication, continue userActivity: NSUserActivity is not going to be called.

Access Universal Link app-argument in AppDelegate

I'm working on implementing Universal Links on our website, and I've run into a seemingly simple issue that I can't figure out. Searching Google and Stack Overflow hasn't helped, which leads me to believe I might just be missing something.
Basically, I'm adding the following to my page header (which has a URL of "https://www.website.com/slug").
<meta name="apple-itunes-app" content="app-id=xxx, app-argument=https://www.website.com/1" />
Note that the app-argument has a different URL than the actual page.
I've setup my apple-app-site-association file properly. When I try and handle the Universal Link in our iOS app, I do this:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard
userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else
{
return false
}
// Set breakpoint here.
return false
}
I set the breakpoint at the last return false, and when I inspect components, it contains the actual page URL ("https://www.website.com/slug") and not the URL passed in via app-argument ("https://www.website.com/id").
So my question is: How do I access the app-argument in my AppDelegate?

How to NOT handle some Universal Links programmatically?

My iOS application handles universal links to redirect safari users to my app. So far everything is working great, if a user tap a link to my web site from Google my app is opening instead of my web site like this:
from safari https://my-web-site.com -> my-app
But my app doesn't implement certains features that my web site does, so I would like to programmatically reject some URLs and let my users on safari instead of redirecting him in my app, like this:
from safari https://my-web-site.com -> my-app
OR
from safari https://my-web-site.com?reject -> safari
That should by possible according to Apple documentation:
It’s important to understand that if your app uses openURL: to open a universal link to your website, the link does not open in your app. In this scenario, iOS recognizes that the call originates from your app and therefore should not be handled as a universal link by your app.
Unfortunately that's not what's appending, instead of staying in safari, my user is redirected to my app for a brief moment, then redirected again to safari like this:
from safari https://my-web-site.com?reject -> my-app (briefly) -> safari
here is my code for AppDelegate.swift:
internal func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard let url = userActivity.webpageURL else { return false }
guard let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true) else { return false }
let params = urlComponents.queryItems ?? []
if params.contains(where: { $0.name == "reject" }) {
// This line should prevent the app from opening according to Apple's documentation
application.open(url)
return false
} else {
return true
}
}
So anyone have an idea how I could make the rejection of an Universal link the way it's described by Apple's documentation ?
note: the rejection of an universal link need to be done programmatically by the app, according to data stored locally. So adding a path exception in the apple-app-site-association file is not an option in my case :
{
"applinks": {
"apps": [],
"details": [
{
"appID": "XXXXXXXXX.com.my-app",
"paths": [
"*",
"NOT /reject"
]
}
]
}
}
If you prefix an entry in the paths array with "NOT" then you can explicitly prevent a match. So in your example you could do something like
["NOT /settings/*", "NOT /activity/*", "/*"]
which would prevent paths with /settings or /activity prefixes, and then match everything else.
Reference

Get parameters from URL while not launching app for the first time in viewWillAppear

we provide some parameters using URL schema and it works well if we launch app for the first time. I have provided a custom initialization in AppDelegate:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if let token = Helper.getQueryStringParameter(url: url.absoluteString, param: AUTH_TOKEN_PARAM) {
tokenFromURL = token
return true
} else {
}
return false
}
However this code does not work if for instance user downloads app, opens it and returns back to the web and presses same button to launch app.
I think I need to check if URL was provided in the viewWillAppear, am I right? How to do that, please help?

iOS App Delegate params dictionary doesn't contain any relevant links

I've added the Branch.io SDK to my iOS project. I have a custom URL scheme which works fine, I've added universal app links which work fine.
Now, I've enabled in my Dashboard the iOS app where I've added my custom URL scheme, custom URL for downloading the app, the App Prefix and the bundle identifier.
In the 'quick links' section I've created a quick link witch has a ["key": "value"] pair for the deep link section and added a redirect again to my jenkins where the ipa can be downloaded.
Now, if I access that link by copy/pasting in mobile safari, without the app installed i'm correctly taken to Jenkins.
At this point I run the app from xcode, and in app delegate I have
branch = Branch.getInstance()
branch.initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: {params, error in
if error == nil {
// params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
// params will be empty if no data found
// ... insert custom logic here ...
print("params: %#", params as? [String: AnyObject] ?? {})
} else {
print(error?.localizedDescription ?? "")
}
})
The issue is here that params always only contains two params:
params: %# ["+clicked_branch_link": 0, "+is_first_session": 0]
I've also implemented
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
let branchHandled = branch.application(application,
open: url,
sourceApplication: sourceApplication,
annotation: annotation
)
if (!branchHandled) {
// If not handled by Branch, do other deep link routing for the Facebook SDK, Pinterest SDK, etc
var handled = false
handled = //this is Facebook handling
guard handled == false else { return true }
} else {
// do some stuff if it's coming from branch
}
return branchHandled
}
My interest is for branch to pass my ["key": "value"] pair in order to have it handled like a deep link at this point, but I don't know what else to try.
The failure of deferred deep-linking could be due to mismatch of Branch key and Branch link for a particular Branch app. Verify the Branch link used for deferred deep-linking is generated using the same Branch key which is used in info.plist of the iOS project.

Resources