llfbandit / app_links

Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter.
https://pub.dev/packages/app_links
Apache License 2.0
220 stars 81 forks source link

can not get initial link on ios support carplay #150

Closed tsunhousam91 closed 2 months ago

tsunhousam91 commented 2 months ago

Describe the bug

My flutter app support carplay, So I changed the AppDelegate and SceneDelegate like #81 and I can not get the link when first time I open the app by clicking link.

--- My AppDelegate --- @implementation AppDelegate

--- AppLinkHelper --- import Foundation import app_links

@objc public class AppLinksHelper: NSObject { @objc public static let shared = AppLinksHelper()

@objc public func handleLaunchOptions(_ options: [UIApplication.LaunchOptionsKey: Any]?) {
    if let url = AppLinks.shared.getLink(launchOptions: options) {
      AppLinks.shared.handleLink(url: url)
    }       
}

@objc public func handleOpen(url: URL) {
    // Handle URL
}

}

--- SceneDelegate --- import UIKit import Flutter import SwiftEventBus import app_links import FirebaseCore import UserNotifications //import FirebaseMessaging @available(iOS 13.0, *) class SceneDelegate: UIResponder, UIWindowSceneDelegate, UNUserNotificationCenterDelegate{ var window: UIWindow?

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    for context in URLContexts {
        AppLinks.shared.handleLink(url: context.url)
    }
}

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    if let url = userActivity.webpageURL {
        AppLinks.shared.handleLink(url: url)
    }
}

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = scene as? UIWindowScene else { return }

    window = UIWindow(windowScene: windowScene)

    let flutterEngine = FlutterEngine(name: "SceneDelegateEngine")
    flutterEngine.run()

    UNUserNotificationCenter.current().delegate = self

    GeneratedPluginRegistrant.register(with: flutterEngine)
    FlutterDownloaderPlugin.setPluginRegistrantCallback({ registry in if (!registry.hasPlugin("FlutterDownloaderPlugin")) { 
    FlutterDownloaderPlugin.register(with: registry.registrar(forPlugin: "FlutterDownloaderPlugin")!) } })
    let controller = FlutterViewController.init(engine: flutterEngine, nibName: nil, bundle: nil)
    window?.rootViewController = controller
    window?.makeKeyAndVisible()

    let carplayChannel = FlutterMethodChannel(name: "carplay_star_app",
                                              binaryMessenger: controller.binaryMessenger)
    carplayChannel.setMethodCallHandler({
        [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in

        if call.method == "loadSong" {
            SwiftEventBus.post("loadSong")
            result("")
        } else if call.method == "updateLoginStatus" {
            let args = call.arguments as? String
            CarPlayDataManager.shared.setLoginStatus(status: args)
            SwiftEventBus.post("updateLoginStatus")
            result("")
        } else {
            result(FlutterMethodNotImplemented)
        }

    })

}

}

llfbandit commented 2 months ago

Well browsing this code is not a lot of fun... Still, it should work by adding checks to the right places.

I may suggest to check if the initial link is coming from UIScene.ConnectionOptions.urlContexts or UIScene.ConnectionOptions.userActivities in scene::willConnectTo...

tsunhousam91 commented 2 months ago

@llfbandit thanks After test, I found when app is closed the link will be passed to scene::willConnectTo

So I try this:

` func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene else { return }

// other code...... if let userActivity = connectionOptions.userActivities.first { self.scene(scene, continue: userActivity) } } `

and it finally worked. thank you

llfbandit commented 2 months ago

Thanks for the feeback!