The missing guide to deep linking in Flutter apps - Part 2, iOS
Google Developer Expert in Flutter & Dart 🚀| Mobile App Development 📱| Tech Advocate 🌐| Women Who Code KL Director
Search for a command to run...
Google Developer Expert in Flutter & Dart 🚀| Mobile App Development 📱| Tech Advocate 🌐| Women Who Code KL Director
Hey! I am so glad to find you. I explored information and got your website from the Google search engine. In my free time, I would like to read your all-latest updates and I'll suggest you to my fellows. https://www.google.com/
Hello, the link to part 1 appears to be broken. In the 'More Articles' below it seems to show the correct link.
Yong Shean have you used Firebase Email Auth with Dynamic Links? I'm trying to set that up now (which is what led me to your blog post), and it seems like Flutter Dynamic Links is getting shut down.
John Tyler Firebase dynamic links is shutting down, yes, which is what led me to find alternative approach. You can check how I set up the alternative in Part 1
Yong Shean do you know what deep link URL needs to be setup for Firebase Email Auth?
John Tyler Hmm no idea, I've not used Firebase email auth before
Yong Shean okay thanks
I've been using Bloc for years. It was my go-to state management solution, and I was comfortable with it. Events go in, states come out. Simple, predictable, testable. So when people kept telling me to try Riverpod, I resisted. Why fix what isn't bro...
I've dealt with my share of performance issues in production Flutter apps. Janky scrolling that makes users think the app is broken. Memory leaks that crash the app after 10 minutes of use. The kind of problems that make you question your life choice...
I've been building Flutter apps for a team of around 5 developers for the past few years. When I started, everyone talked about Clean Architecture like it was the only "professional" way to build apps. So naturally, I tried it. After months of writin...
Recently I talked about how to perform automated end-to-end testing on any mobile apps (yes, any, even those you don’t own) with Maestro.Deck: https://excalidraw.com/#json=YBaTDvWm8yTdshL8Z2IOL,7h7736K_Ey7wg08QljkbPg
Recently I gave a talk at Google DevFest Georgetown 2024, about asynchronous Dart features (now with quizzes built in!). Here are the slides I promised:
If you've missed the first part, you can read here.
What you need to do:
Adjust Info.plist
Add "Associated Domains" capability to each bundle ID
Host the apple-app-site-association file
Test with a simulator or a real device, or via the XCode CLI
User walker_Jayce shared his gotchas when he was implementing deeplink, which I have now included in this article - see original comment here. Do check out his other Flutter notes on Github too.
Info.plistOverall, the setup for iOS has relatively less quirks and the official guide covers almost everything you need. However, when you are updating the Info.plist file, take note if you are using app_links package you should not include the FlutterDeepLinkingEnabled property.
Follow the official guide. Apart from setting the associated domain(s) in XCode, you should also remember to set the same in Apple Developer Portal (Certificates, Identifiers & Profiles > Identifiers > Select an identifier > Capabilities).
apple-app-site-association fileSimilar to assetlinks.json , you would also need to host the Apple-equivalent file on your web server. However, unlike Android, iOS universal links must be in https, which some internal test servers may not be.
The directory to host is the same (.well-known), only the file name is different: <webdomain>/.well-known/apple-app-site-association . You can apply the same tip to host it with Firebase Hosting if you don't already have a web server and update the web domain accordingly.
You can also associate a single web domain with multiple app IDs, e.g. when you have different flavours of the app, like so:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "<team_id>.com.example.myapp.dev",
"paths": ["*"]
},
{
"appID": "<team_id>.com.example.myapp.qa",
"paths": ["*"]
},
{
"appID": "<team_id>.com.example.myapp",
"paths": ["*"]
}
]
}
}
You can configure the domain association to only match a specific path of the web domain, especially when you only want a certain paths to be redirected to your app. It can also support advanced matching, as showcased here.
Similar to that in Android, make sure you have reinstalled the app after you have done the above steps, you can type a URL in a separate app (e.g. in a Note app, or send an email to yourself, or type in a Google Doc) and then tap on the URL (note: typing or pasting the URL in the browser would not work!). It should navigate to the app and open the specific screen correspondingly.
Alternatively, you can run this command to trigger: xcrun simctl openurl booted https://<web domain>/details . There is also a warning in the official guide that it might take up to 24 hours before Apple’s Content Delivery Network (CDN) requests the apple-app-site-association (AASA) file from your web domain, so the app link won’t work until the CDN requests the file.
Here are some additional troubleshooting tips (thanks walker_Jayce!):
When testing, check if your link ends with a ., if yes you will have to use apps like this and this to launch the links, since most text editors will not include the . when clicking and open the link.
If you would like to test deep links on a server not reachable by Apple CDN, you can use Associated Domains Development to force your device to fetch the json file directly. Apple's video discussing this, start at 18:22
Enable Developer Mode (Settings > Privacy & Security > Developer Mode)
Enable Associated Domains Development (Settings > Developer > Section: Universal Links > Associated Domains Development) and insert internal link in Diagnostics to fetch the apple-app-site-association file. (the Developer section is quite low, so scroll lower, should be just before your 3rd party apps section)
You can check if your file is hosted correctly on Apple's CDN by launching this link, replace <your website link> with your own link: https://app-site-association.cdn-apple.com/a/v1/<your website link>
If your rootViewController is not a FlutterViewController (if you somehow overwritten it in your AppDelegate.swift file), you may need to manually add code to capture the request from iOS side.
Alright, that's all for the deep linking. Let me know if I missed something, leave a comment if you find this kind of guide useful, so I'd be motivated to write more :D