[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter should provide tutorial for setting up universal link in iOS #7913

Closed
chunhtai opened this issue Dec 5, 2022 · 20 comments · Fixed by #8266
Closed

Flutter should provide tutorial for setting up universal link in iOS #7913

chunhtai opened this issue Dec 5, 2022 · 20 comments · Fixed by #8266
Assignees
Labels
cl.fixed Issue is closed as fixed d.enhancement Improves docs with specific ask e2-days Effort: < 5 days

Comments

@chunhtai
Copy link
Contributor
chunhtai commented Dec 5, 2022

Currently the https://docs.flutter.dev/development/ui/navigation/deep-linking only provide steps to set up custom schema for iOS, It should also provide steps to set up universal link.

@chunhtai
Copy link
Contributor Author
chunhtai commented Dec 5, 2022

cc @johnpryan

@chunhtai
Copy link
Contributor Author
chunhtai commented Dec 5, 2022

Two ways to set up the universal link

through xcode:

  1. open ios folder in xcode, in the signing & capacbilities tab
  2. click + button on the top left in the page
  3. select associate domain
  4. in the newly create associate domain section, click + to add applinks:

manually:

  1. open ios/Runner.xcodeproj/project.pbxproj in ide
  2. search for CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; (should have found three occurrences, one for each Debug,Profile,Release)
  3. add the following line above the line CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; for all three occurrences
  4. create a file ios/Runner/Runner.entitlements, with the following content
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.associated-domains</key>
	<array>
		<string>webcredentials:example.com</string>
		<string>applinks:example.com</string>
	</array>
</dict>
</plist>

@YOoOUNiieeSS
Copy link

i made these steps and it didn't work. i got this from system diagnose

Service: applinks
App ID: ...*
App Version: 33.0
App PI: <LSPersistentIdentifier 0x105310f70> { v = 0, t = 0x8, u = 0x99c, db = ----**, {length = 8, bytes = 0x9c09000000000000} }
Domain: example.com
User Approval: unspecified
Site/Fmwk Approval: denied
Flags:
Last Checked: 2022-12-06 08:50:43 +0000
Next Check: 2022-12-11 08:42:31 +0000

Service: webcredentials
App ID: ...
App Version: 33.0
App PI: <LSPersistentIdentifier 0x105310f70> { v = 0, t = 0x8, u = 0x99c, db = **----, {length = 8, bytes = 0x9c09000000000000} }
Domain: example.com
User Approval: unspecified
Site/Fmwk Approval: denied
Flags:
Last Checked: 2022-12-06 08:50:43 +0000
Next Check: 2022-12-11 08:42:31 +0000

@AristideVB
Copy link

Hi this could indeed be a great addition to the Flutter documentation !

In case anyone has the same issue as me, I've actually followed this exact steps & universal link works in iOS simulator but not on a real iOS device

seems to be related to https://developer.apple.com/forums/thread/720917

In such cases where the app and server configuration is correct, the problem is often that the AASA file can't be accessed from arbitrary IP addresses, either because of your server configuration or because of a security constraint from your network security provider. If you can't make any progress solving this, I suggest you open a code-level support incident with Developer Technical Support (https://developer.apple.com/account/#CodeLevelSupportCard) so that DTS can look into what's gone wrong.

@johnpryan
Copy link
Contributor

Just to clarify - do we have an issue to document Android App Links too?

@chunhtai
Copy link
Contributor Author
chunhtai commented Dec 6, 2022

No We don't have one

@johnpryan johnpryan transferred this issue from flutter/flutter Dec 6, 2022
@johnpryan
Copy link
Contributor

Transferring this issue to flutter/website

@johnpryan johnpryan added d.enhancement Improves docs with specific ask e2-days Effort: < 5 days and removed documentation labels Dec 6, 2022
@johnpryan
Copy link
Contributor

App links issue: #7914

@chunhtai
Copy link
Contributor Author
chunhtai commented Dec 8, 2022

I tested a little bit and found the following.

  1. manually modifying Runner.xcodeproj/project.pbxproj and Runner/Runner.entitlements doesn't work out of the box, I have to open xcode and remove and re-add the applinks and run the app in order for the universal link to work. Not sure if xcode modify any other file other than these two file to wire up universal link. Need more investigation.
  2. universal link doesn't seem to pass the route to flutter, I am not sure if this is a setting problem or a flutter engine problem. I think it is the later. I will need to investigate more.

@chunhtai
Copy link
Contributor Author
chunhtai commented Dec 8, 2022

It looks like I forgot to set the flag in info.Plist, otherwise things work correctly.

@chunhtai chunhtai self-assigned this Dec 12, 2022
@AristideVB
Copy link

I've finally got universal links to open my app on iOS but universal link doesn't pass the route to Flutter as you've experienced @chunhtai have you found a solution to this issue ? : )

@chunhtai
Copy link
Contributor Author

@AristideVB have you set

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

in info.pList ?

@AristideVB
Copy link

I had not, I thought that was only for deeplinking & not universal links !

Universal links works now with this flag enabled, thanks so much @chunhtai 🙂

@AristideVB have you set

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

in Info.plist ?

@chunhtai
Copy link
Contributor Author
chunhtai commented Jan 3, 2023

sorry for the confusion. I will have a more detailed tutorial up with all the requirements and steps sometime soon.

@kosidinma
Copy link
kosidinma commented Jan 25, 2023

Hi @chunhtai @AristideVB

I was wondering if you could also look through my issue pending the documentation readiness and help me rectify.:

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

I also tried adding a component that hardcoded a path in my app, still got same results. Basically "/": "/feed" as a component but when I clicked www.example/feed, same result...it just opened the app.

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

Flutter Doctor -v output:
[✓] Flutter (Channel stable, 3.3.8, on macOS 13.1 22C65 darwin-x64, locale en-GB)
• Flutter version 3.3.8 on channel stable at /Users/kosidinma/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 52b3dc25f6 (3 months ago), 2022-11-09 12:09:26 +0800
• Engine revision 857bd6b74c
• Dart version 2.18.4
• DevTools version 2.15.0

[✗] Android toolchain - develop for Android devices
✗ Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
flutter config --android-sdk to update to that location.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 14B47b
• CocoaPods version 1.11.3

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (not installed)
• Android Studio not found; download from https://developer.android.com/studio/index.html
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).

[✓] VS Code (version 1.74.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.56.0

[✓] Connected device (3 available)
• iPhone SE (3rd generation) (mobile) • FBED5E0B-AB31-4685-A844-34A44882BE25 • ios • com.apple.CoreSimulator.SimRuntime.iOS-16-1
(simulator)
• macOS (desktop) • macos • darwin-x64 • macOS 13.1 22C65 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 109.0.5414.87
! Error: kosynom’s iPhone has recently restarted. Xcode will continue when kosynom’s iPhone is unlocked. (code -14)

[✓] HTTP Host Availability
• All required HTTP hosts are available

! Doctor found issues in 2 categories.

@kosidinma
Copy link

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
  }

Taking that function out and just having this in my info.plist worked (everything else stayed the same):

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

@zoeyfan
Copy link
Contributor
zoeyfan commented Feb 9, 2023

Meanwhile, as we think about revamping our docs page for deep linking, I would like to request we not only add the iOS section but also expand the existing Android section with more step-by-step guidance. Can we incorporate John's talking points from the recently launched deep-linking video (https://www.youtube.com/watch?v=KNAb2XL7k2g)?

@johnpryan
Copy link
Contributor
johnpryan commented Feb 9, 2023

Here's the issue to track documentation for App Links: #7914

@chunhtai
Copy link
Contributor Author
chunhtai commented Mar 7, 2023

@danagbemava-nc danagbemava-nc added the cl.fixed Issue is closed as fixed label Mar 8, 2023
@timovandeput
Copy link
timovandeput commented Sep 1, 2023

I followed the documentation, but failed to get my universal link working for iOS. (The recipe for Android works perfectly.)

My experience matches this existing issue: flutter/flutter#123985

I do see from the server logs that in "developer" mode the association file is read, but when triggering the simulator with the indicated xcrun simctl openurl booted https://{MY_DOMAIN} command it still opens the website.

Any thoughts on what might be missing, or how to debug at the app side what could be causing the problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cl.fixed Issue is closed as fixed d.enhancement Improves docs with specific ask e2-days Effort: < 5 days
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants