swiftflutterios-universal-linksflutter-iosapple-app-site-association

Flutter IOS Universal Link Opens App, But Does Not Navigate To Correct Page


I have set up Universal Links on my flutter project for IOS.

Like the title suggests, my app does open when I click on a link relating to my site but it does not navigate to the correct page. It just opens the app. I'm not using the uni_links package, rather I used a combination of guides (including official documentation):

https://developer.apple.com/videos/play/wwdc2019/717/

https://nishbhasin.medium.com/apple-universal-link-setup-in-ios-131a508b45d1

https://www.kodeco.com/6080-universal-links-make-the-connection

I have setup my apple-app-site-association file to look like:

{
    "applinks": {
        "details": [
            {
                "appIDs": [
                    "XXXXXXX.com.my.appBundle"
                ],
                "componenents": [
                    {
                        "/": "/*"
                    }
                ]
            }
        ]
    }
}

and I have added this to my info.plist file:

<key>FlutterDeepLinkingEnabled</key>
<true/>

and my AppDelegate.swift file looks like:

import UIKit
import Flutter
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(_ application: UIApplication, continue userActivity: NSUserActivity, 
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    // This will allow us to check if we are coming from a universal link
    // and get the url with its components
    // The activity type (NSUserActivityTypeBrowsingWeb) is used
    // when continuing from a web browsing session to either
    // a web browser or a native app. Only activities of this
    // type can be continued from a web browser to a native app.
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
      let url = userActivity.webpageURL,
      let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
        return false
    }
    // Now that we have the url and its components,
    // we can use this information to present
    // appropriate content in the app
    return true
  }

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

My Runner-entitlements are also setup correctly like:

<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:www.example.com</string>
    <string>applinks:*.example.com</string>
</array>

The issue is, if I click a hyperlink for www.example.com/mypath , it does not got to the page/route handled by /mypath, but instead just opens the app.

My routing is done using go_router: ^5.2.4

Please does anyone know why this is happening? I'm blocked by this. I have seen similar questions, but none with answers that have worked for me. Any help is appreciated.


Solution

  • Ok so figured it out. The official apple documentation requests the addition of a variation of this function in the AppDelegate.swift file:

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, 
        restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        // This will allow us to check if we are coming from a universal link
        // and get the url with its components
        // The activity type (NSUserActivityTypeBrowsingWeb) is used
        // when continuing from a web browsing session to either
        // a web browser or a native app. Only activities of this
        // type can be continued from a web browser to a native app.
        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
          let url = userActivity.webpageURL,
          let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
            return false
        }
        // Now that we have the url and its components,
        // we can use this information to present
        // appropriate content in the app
        return true
      }
    

    Seems that it conflicts with the flutter framework for handling universal links. Taking that function out and just having this in my info.plist worked (everything else stayed the same):

    <key>FlutterDeepLinkingEnabled</key>
    <true/>
    

    Flutter documentation is not out for this (as at the time of posting this answer) so if people are interested, I could do a small article on the necessary steps.