iOS Universal Links are not opening in-app
IosObjective CXcodeIos9Ios Universal-LinksIos Problem Overview
So I followed this tutorial exactly and use the same values as the ones provided: https://blog.branch.io/how-to-setup-universal-links-to-deep-link-on-apple-ios-9
The Apple Association file is also ready in the link directory:
WEB_PAGE:PORT_NUMBER/apple-app-site-association
Everything seems to be set up on this side.
I've added the entitlements, updated the provisioning profile, and everything's set up.
When I run the app on my device, and open the link http://WEB_PAGE:PORT_NUMBER
, this always opens Safari.
I even have breakpoints in the following method:
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler
But zilch.
Has anyone perfected this? Is there something I'm missing?
Ios Solutions
Solution 1 - Ios
There are a few possible issues.
-
Try pasting your domain into this link validator and make sure there are no issues: https://limitless-sierra-4673.herokuapp.com/ (credit to ShortStuffSushi -- see repo)
-
iOS logs an error message in the system logs if you don't have TLS set up properly on the domain specified in your entitlements. It's buried in the OS logs, not application logs. The error message will look like
Sep 21 14:27:01 Derricks-iPhone swcd[2044] <Notice>: 2015-09-21 02:27:01.878907 PM [SWC] ### Rejecting URL 'https://examplecustomdomain.com/apple-app-site-association' for auth method 'NSURLAuthenticationMethodServerTrust': -6754/0xFFFFE59E kAuthenticationErr
. Error message pulled from here, quick (incomplete) instructions on using CloudFlare for TLS here. -
In my personal testing, clicking/typing in a link in Safari has never once opened the app directly. Clicking from other apps (iMessage, Mail, Slack, etc.) has worked. Others have reported that clicking links in Google search results have opened the app directly.
-
Note that if a Universal Link succeeds in opening your app and then you click through to Safari (by tapping your site in the top right corner of the nav bar in app), then iOS stops opening the app when you visit that URL. Then in Safari, you can pull down to reveal a banner at the top of the page with "Open". I wasted a lot of time on this. Note that clicking through to the site => disabling UL seems path specific, based on the paths you specify in the apple-app-site-assocation file. So if you have separate routes,
yoursite.com/a/*
andyoursite.com/b/*
, if you clickyoursite.com/a/*
and it opens your app directly, you then have the option in the top right corner of the app to click through toyoursite.com/a/*
. If you do that, subsequent visits toyoursite.com/a/*
will open in browser, not app. However,yoursite.com/b/*
should be unaffected and still open your app directly.
Let me know if you discover what the issue is. I'm personally very curious about how Universal Links work and what edge cases exist. Good luck.
Solution 2 - Ios
There are a lot of ways this can go wrong. Two points caused me trouble:
-
In Xcode, when you add the Associated Domains entitlement, each entry needs to start with
applinks:
and then your domain name. E.g.applinks:www.apple.com
. -
Though Xcode created an entitlements file for me, it did not include in my build: I had to click that box manually.
And yes, after doing that, it wasn't necessary to sign the apple-app-site-association
file: it is just plain text, and it works, as long as it's served over HTTPS. (You'll still need to sign it if you're supporting iOS 8, though.)
Solution 3 - Ios
To help debugging this issue, search for "swcd" in your device's console output when installing your app to see if registering your universal link worked or failed.
- Use an actual device, not the simulator.
- Delete the app from you device.
- Connect the device to your computer, and view the device's console output in xcode. (window -> devices -> [your device] -> open console). Keep this window open.
- Install your app and let it launch.
- Filter the console output to "swcd". If it's sucessful you will see something like the folowing screenshot. If it fails you'll see something else. If you don't see anything then you messed something fundamental like adding the Associated Domains entitlement.
Solution 4 - Ios
There is apparently an error in the documentation for making the association file for Universal Links.
Where it says:
> The value of the appID key is the app’s team ID and the bundle ID
it should say
> The value of the appID key is the app’s Prefix and the bundle ID
For most apps, it seems that the Team ID and app prefixes are the same, but if your app has been in the store for many years, these values can be different.
To find this value, open the Member Center on https://developer.apple.com and look at "Certificates, Identifiers & Profiles", click "Identifiers", then "App IDs" in the table under "Identifiers". Find your app, and use the Prefix value and Bundle ID there to create your AppID for the association file.
Solution 5 - Ios
To validate apple-app-site-association
on the server side, you can
use Apple's official validator.
https://search.developer.apple.com/appsearch-validation-tool/
Solution 6 - Ios
St.derrick's [Answer](https://stackoverflow.com/a/32751734/127493 "answer") is informative.
But to enable universal links again to open in app instead of safari we need to do the following thing.
- Long press on Universal link in Mail or iMessage, then you will see options whether to open in safari or in App.
Solution 7 - Ios
I realized that be problem for me was that links to the root directory a (eg. http://example.com/
) did not open my app but if I added a path (eg. http://example.com/mypath
) it worked. Adding "/"
to the paths list sovled it:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAM_ID.BundleIdentifier",
"paths": [ "*", "/" ]
}
]
}
}
As answered by slutsker in this Apple Developer Forums thread.
Solution 8 - Ios
Quick steps to check whether you have implemented Universal Link correctly.
-
Tap and hold on the link that you expect to launch the app. You should see a "Open in [your app name]" in the Context Menu.
-
Open Notes app, type the link you expect to open the app. Tap Done. The link will turn yellow and tapping on the link should open your app, and not Safari.
-
If the link http://yourDomain.com is not launching the app, try http://yourDomain.com/yourFolder/
-
In Safari, If the Context Menu shows "Open in [your app name]" in safari, but tapping the link opens the link in safari itself instead of launching the app,
a. Try pulling down on the safari page that opened when the link was clicked like the way you 'pull to refresh'. A banner should appear that can open your app. Tap the banner to open the app, close the app by pressing home button, get back to safari and try launching the app by tapping the link again. This time on, the app should get launched because tapping the banner should have saved the preference to open the link in app.
b. If the app still don't get launched after the step a., try mailing the link to a webmail such as gmail and open the webmail site in safari and try clicking the link. If this works, you may have been trying to launch the app from the same domain as the link. From what I have seen, launching the app from the same domain mostly fails. Probably safari wont care to check whether the destination url is a universal link, when the link is into the same domain that user is on. So try to launch the app from another domain.
Solution 9 - Ios
For anyone who needs to easily test opening (Universal) Links, you can also open the link in your Simulator from the terminal with this command:
xcrun simctl openurl booted yourapp_or_http://yourlink
for example:
xcrun simctl openurl booted https://www.google.com
Solution 10 - Ios
It's also super important to increment the project version or build number after integrating universal links. Even if you delete/reinstall, iOS won't pickup the links unless you bump the version.
Solution 11 - Ios
-
Universal Links will not work if you paste the link into the browser URL field.
-
Universal Links work with a user driven
<a href="...">
element click across domains. Example: if there is a Universal Link on google.com pointing to bnc.lt, it will open the app. -
Universal Links will not work with a user driven
<a href="...">
element click on the same domain. Example: if there is a Universal Link on google.com pointing to a different Universal Link on google.com, it will not open the app. -
Universal Links cannot be triggered via Javascript (in window.onload or via a .click() call on an
<a>
element), unless it is part of a user action.
The 3rd bullet cost me about a day to figure out.
Solution 12 - Ios
Incase people here are looking for other solutions, we put together a whole step-by-step on debugging Universal Links as we've seen a lot of issues pop up, causing a LOT of headaches.
Check it out:
Universal Links Debugging Guide
If you're just looking to set up Universal Links fresh, this guide is really helpful:
Hope they're helpful!
Solution 13 - Ios
Just thought I would add some things I discovered in case more people encounter the same issues as me in the future. These are mostly related to authentication errors.
Even though apple doesn't explicitly state it, the apple-app-site-association
file must be served over https, even if signed. The certificate used for https must also be trusted by apple. So while a certificate added to the device in Settings -> General -> Profiles will allow https in safari, it will not allow universal links to work.
In the device logs, on an authentication error between the device and the server, there will be a value printed like "TrustResultValue" : 4
. A TrustResultValue
of 5 means the certificate is for the wrong domain (Eg. test.com served from www.test.com). A TrustResultValue
of 4 means the certificate is not trusted for this use.
There may be some helpful steps for debugging here. The "Testing access to apple-app-site-association" section is a step by step guide for how to make sure the device is getting the apple-app-site-association
file. The steps boil down to:
-
Uninstall the app. This is necessary because the file is downloaded on install.
-
Stop the server from properly serving
apple-app-site-association
. -
In xcode, open Window -> Devices and then select your device.
-
Open the device logs by clicking the triangle at the bottom of the window.
-
Clear the logs by clicking the trashcan to clear any previous logs that might be related.
-
Reinstall the app with xcode by clicking the play button.
-
After the app has launched, if the device is correctly requesting the file then the device logs should contain an error that can be found by searching for "apple-app-site-association".
If the apple-app-site-association
file is properly served (step 2 is left out) then there should be no error. An authentication error may instead be displayed if that is the problem.
Solution 14 - Ios
The most common cause is when user tap on the top right, thus telling iOS to NOT open the app (in this case Uber) in the future.
To fix, pull down to reveal the smart banner and tap on OPEN:
This will subsequently "remember" to open the app.
Solution 15 - Ios
We've added apple-app-site-association file to this location:
https://example.com/apple-app-site-association
On iOS 9 it worked fine, but on iOS 10 it didn't work.
It appeared that problem was with .well-known path:
https://example.com/.well-known/apple-app-site-association
Because of https://example.com/.well-known/apple-app-site-association path redirected to https://example.com
<Notice>: Allowing redirect 'https://example.com/.well-known/apple-app-site-association' -> 'https://example.com/'
<Notice>: ### Rejecting AASA file size 154466 for URL https://example.com/.well-known/apple-app-site-association
In my opinion if somehow .well-known path doesn't work correctly it breaks universal links.
Solution 16 - Ios
After spending a day trying to get this to work, Restarting my phone solved the problem.
Uninstalling/Reinstalling the app didn't work either.
Solution 17 - Ios
For ios13, there is a new format - check out here https://developer.apple.com/documentation/safariservices/supporting_associated_domains_in_your_app?language=objc
I updated my file to look like this:
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": ["1234.app.company.appname"],
"appID": "1234.app.company.appname",
"components": [
{
"/": "/login"
}
],
"paths": [ "/login" ]
}
]
},
"webcredentials": {
"apps": ["1234.app.company.appname"]
}
}
Solution 18 - Ios
I've managed to make it work, but it took quite some time and struggle. Note that unless you sign the apple-app-site-association
file (signing is optional!) tapping on a link in Safari will not open your app (it has caused me a lot of headache).
Solution 19 - Ios
Took me close to a day to figure this out. The issue I had was not downloading the updated provisioning profiles in XCode (I also restarted XCode after this).
> (Preferences > Accounts > View Details > Download All)
Solution 20 - Ios
>You can test universal links in simulator
From the App Search Programming Guide: Support Universal Links
Solution 21 - Ios
After two days it turned out for me, that these kind of links (from branch)
> applinks:xxxx.app.link
work only after Archiving (also Ad-hoc) the application and install it to the phone.
Solution 22 - Ios
If you are hosting your apple-app-site-association
on Firebase, make sure to put it in /.well-known/
subdirectory! It appears that Xcode queries that URL first, and if it succeeds, it makes no attempt to query the apple-app-site-association
in the root directory. For some reason, firebase engineers made the hosted websites to automatically respond to /.well-known/apple-app-site-association
with an empty (but correctly formed) association file that overrides your custom one, leaving you with no clue why nothing works!
Solution 23 - Ios
Go to developer.apple.com and edit one of your distribution profiles. In the editing page you can open a pop up for App IDs that will show a list of your app names and in () round brackets behind the app's name it reveals all your real App IDs. Some apps might have your team ID as prefix but some do not. Make sure to use exactly what you see in that pop up menu inside the () and put it into the apple-app-site-association details appID field. I had exactly this issue with an app and its universal links.
Solution 24 - Ios
The issue for me turned out to be the apple-app-site-association
file. According to Apple's documentation, only the applinks parameter is required. I added the activitycontinuation
parameter and it worked.
{
"activitycontinuation": {
"apps": [
"9JA89QQLNQ.com.apple.wwdc"
]
},
"applinks": {
"apps": [],
"details": [{
"appID": "9JA89QQLNQ.com.apple.wwdc",
"paths": [ "/wwdc/news/", "/videos/wwdc/2015/*" ]
}]
}
}
Solution 25 - Ios
Haven't really seen the exact same issue/solution combo that got it working for me so might as well add mine incase someone has the same problem!
For my app I am using a custom URL scheme (set in APP_TARGET > Info > URL Types
) and set the URL scheme from here into the Firebase console to match but still wasn't working.
My problem was actually two problems:
Watch out if checking Automatically Manage Signing
If you are checking Xcode's "Automatically manage signing" setting like I was, since I was just trying to make a quick demo app, you will want to ensure that the TeamID that is used matches the one in your Firebase console. I originally went to my Apple Developer Account and copied the team ID from my Membership page, but later saw that the actual ID being used by Xcode was different. (You can find this in APP_TARGET > General > Signing > Signing Certificate.
For me it looked like iPhone Developer: My Name (TEAM_ID)
).
Prefix your TeamID to your Bundle Identifier in your URL Types
After I ensured these matched in my Firebase console and Xcode, my next problem was the identifier for my URL scheme. It's typical to use your bundle identifier here, but Firebase actually prefixes this with the Team ID you gave in your Firebase console, so I had to prefix it to the identifier in the URL types section in Xcode as well.
After these two fixes and re-downloading the GoogleService-Info.plist
file I had no problem open up my dynamic links.
Solution 26 - Ios
After two days of total desperation, I think I've finally fixed it. Here is my solution:
It seems that older apps use a different app prefix than newer apps. Newer apps only use the Team ID for this purpose. If the app prefix and the team ID are not identical, it seems that you need to specify the activity continuation field in the apple app site association file:
{
"activitycontinuation": {
"apps": [
"YOUR_APP_PREFIX.de.company.app"
]
},
"applinks": {
"apps": [],
"details": [
{
"appID": "YOUR_APP_PREFIX.de.company.app",
"paths": ["/*"]
}
]
}
}
Another thing I experienced during my hell ride was that deleting the app and restarting the device seems to be the only way to force refresh this file.
Solution 27 - Ios
In my case I needed to make the server serve the apple-app-site-association
file using content type: application/pkcs7-mime
. In nginx I did it using this approach:
location ~ /.well-known/apple-app-site-association {
default_type application/pkcs7-mime;
}
As other suggested I also had to make sure I:
- Use the new iOS
apple-app-site-association
format https://developer.apple.com/documentation/safariservices/supporting_associated_domains - Use the correct TEAM ID so it becomes
"appIDs": [ "TEAM_ID.my-app-bundle-id"],
- Make sure in Xcode's entitlements, the app associations start with
applinks:
Note that I never saw the "success" messages in the Console app as shown in screenshots by another user. In the console I kept getting Entry [...] needs its JSON updated because the app PI changed
, but this was not an issue.
Also note that when trying to open the apple-app-site-association
in the browser, the file gets downloaded instead of displayed, but this was not an issue in my case.
And as always, use a real device, re-install app whenever you change things, potentially also restart device and maybe increment app version number.
Solution 28 - Ios
Sometimes I find that everything is fine with the association file but iOS decides to always open the universal link in Safari. To test if the app recognises the app link I add the URL to Notes or a Calendar entry and then long press it so the contextual menu appears. If it says "Open in {YOUR APP}" then the link is working but iOS is deciding to open it in Safari. Tapping "Open in {YOUR APP}" will tell iOS to open valid universal links via your app from then on.
Solution 29 - Ios
For me, my error was our site is redirecting www.domain.com to domain.com, so all the www.domain.com/* will fail because of that. Hope that helps.
Solution 30 - Ios
For future readers that find this page ...
I had a similar situation. However, in my situation, iOS10 was working AOK, and no matter what I did (bump build numbers, delete/reinstall, etc), iOS9 seemed to refuse to work.
I was coming to this from iOS10, and needed to support iOS9. At the time, the documentation here - https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html - clearly states that the file may be placed at the root of the web-server (e.g. /apple-app-site-association
) or in the .well-known folder (e.g. /.well-known/apple-app-site-association
). Because I'm also supporting Android, which also uses the .well-known folder for a similar file, I decided to put both in there.
For fresh installs on iOS10, it clearly request the root file, fails, then requests the .well-known file, and succeeds.
For iOS9, it clearly requested the root file, fails, and does nothing else.
Solution: if you support iOS9, put the file at /apple-app-site-association
.
Solution 31 - Ios
I was able to test Universal Links in the iOS Simulator by using the Calendar app.
I just created an event and added the URL I wanted to test in the event's URL
field. Then, when viewing the created event, you can simply tap on the URL link and your app should open.
Solution 32 - Ios
For me, after implementing all the answers from above and testing that the AASA file was indeed being downloaded with mpoisot's answer, my issue was that in Xcode I added the associated domain as:
applinks:example.com
and in my notes app I was trying to use:
Https://example.com
because my AASA is not signed and I wanted to ensure I was serving it through HTTPS. So it worked when in my notes app I tried to use:
example.com
It works for me on a physical device, using iOS 12.1.2 with either a development build from Xcode or a distribution build from Testflight
Solution 33 - Ios
Hope this helps someone because this took me about two days to figure out.
We had to add www.
to our associated-domains
in our .entitlements
file.
<string>applinks:www.yourdomain.com</string>
<string>activitycontinuation:www.yourdomain.com</string>
Because if we used yourdomain.com
instead of www.yourdomain.com
our servers did a redirect -> 304 and then didn't include the content-type: application/json
for the apple-app-site-association file
.
N.B. the universal links still work for yourdomain.com
and www.yourdomain.com
Solution 34 - Ios
The reason in my case was an invalid JSON.
It didn't use " but ” because I copied it from some article and the "expert" author of the article put it with the signs like that, and I copied it from him.
BTW, there is still not the information box on the target site anyway like "you can open it with the app" but if i click the link eg from Notes app the app is opened.
wrong:
{
“applinks”: {
“apps”: [],
“details”: [
{
“appID”: “T5TQ36Q2SQ.com.reddit.production”,
“paths”: [“*”],
}
]
}
}
good:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "T5TQ36Q2SQ.com.reddit.production",
"paths": ["*"],
}
]
}
}
Solution 35 - Ios
In my cas it was not woking because I had 2 items in
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:urlOne</string>
<string>applinks:urlTwo</string>
</array>
</dict>
</plist>
when I reduce array to only one item it start to work.
Solution 36 - Ios
There is a new format for file - check this link: https://developer.apple.com/documentation/safariservices/supporting_associated_domains_in_your_app?language=objc
I updated my file like this:
"applinks": {
"apps": [],
"details": [
{
"appID": "APP_ID_PREFIX.BUNDLE_ID",
"paths": [
"*"
]
}
]
},
"webcredentials": {
"apps": [
"APP_ID_PREFIX.BUNDLE_ID"
]
}
}
Note: In simulator it`s not working but, on device working perfectly.
Solution 37 - Ios
In my case my error was to put query parameters in paths:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAM_ID.BundleIdentifier",
"paths": [ "/auth-ui/hub?target=confirm&*" ]
}
]
}
}
when I remove '?target=confirm&*' from paths, it start to working
Solution 38 - Ios
In my case, the request for the AASA file at: https://example.com/apple-app-site-association
Was being redirected to: https://www.example.com/apple-app-site-association
The kicker is -- this works fine on iOS 11, but fails on iOS 9.3.5. Go figure.
Solution: the apple-app-site-association
file MUST NOT be behind a 302 or 301 redirect for iOS 9. (To be fair, this is noted on the UL troubleshooting page.)
Solution 39 - Ios
I'll also put my notes on troubleshooting.
Basically we have 2 parts, that should be linked together: 1) web site and 2) an iOS app.
-
For the web site there was only one issue: MIME type for
apple-app-site-association
file was notapplication/json
.Also API Validation Tool wasn't helping us, for
test
environments it was saying
> Error no apps with domain entitlements The entitlement data used to verify deep link dual authentication is from the current released version of your app. This data may take 48 hours to update.
but in the end web site was ok.
We checked web logs, saw GET request to apple-app-site-association
file and decided to switch to iOS app.
- For dealing with iOS app setup it is good to have
Console
app running, with filtering for showing onlyswcd
process, as was already mentioned in this thread.
In our case the issue was that we rely on wildcard URL, in the form: applinks:*.prod_site_name.com
, thinking that * will cover all test environment prepending, like https://test_env.num4.prod_site_name.com
, but this is not working. Console was showing:
> Started request for domain '*.prod_site_name.com', URL 'https://prod_site_name.com/.well-known/apple-app-site-association'
So the fix in our case was to provide test-specific applinks for test target of the app, like: applinks:test_env.num4.prod_site_name.com
Solution 40 - Ios
I did not see someone provide a solution for Flask.
This worked for me.
EDIT: After two down-votes, I'd like to clarify that I still use this exact solution months later. It does work, but there are other reasons why it might not work immediately for your app. This includes that you will have to delete the app and restart your phone several times even. Eventually, it links. I'm not sure why it is so difficult, but this solution does work. So keep trying, and if you have any issues, feel free to comment them so I can try to help.
If you are using Flask, put the "apple-app-site-association" in your static folder, and then add this to your application.py file.
@application.route('/apple-app-site-association', methods=['GET'])
def apple_app_site_association():
return application.send_static_file('apple-app-site-association')