方法'scene(_:openURLContexts:)'没有被调用。

33

我已经成功地在info.plist文件中配置了URL IdentifierURL Scheme。同时,我也能够使用自定义URL打开应用程序。问题是当应用程序首次启动时,方法

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) 

不会被调用。

我有一些依赖于上面方法的功能。因此,当应用程序首次启动时,我无法在我的应用程序中看到任何内容。

另外我在这个方法中添加了代码。

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

但是在这里我得到的URL为nil。

然而,如果我的应用程序处于后台模式并且我点击URL,则上述方法成功调用并且相关功能正常工作。以下是我在sceneDelegate中的scene(_:openURLContexts:)方法的代码。

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>){
        let url = URLContexts.first?.url
        let urlString: String = url!.absoluteString
        
        if let urlComponents = URLComponents(string: urlString),let queryItems = urlComponents.queryItems {
            queryParams = queryItems
        } else {
            print("invalid url")
        }
        
        guard let windowScene = (scene as? UIWindowScene) else { return }


        self.window = UIWindow(windowScene: windowScene)
        //self.window =  UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let rootVC = storyboard.instantiateViewController(identifier: "LocationViewIdentifier") as? UIViewController else {
            print("ViewController not found")
            return
        }
        let rootNC = UINavigationController(rootViewController: rootVC)
        self.window?.rootViewController = rootNC
        self.window?.makeKeyAndVisible()
    }

有谁能告诉我为什么第一次上述方法没有调用吗?


1
这个问题目前的状态是什么?有没有一个答案解决了你的问题?如果是,可以接受其中一个答案吗?你还需要更多的帮助吗?如果是,能否解释一下提供的解决方案对你的问题做了什么,还有什么是缺失的?我很乐意帮助你解决这个问题。 - emmics
4个回答

35

也许这能帮助您的情况。


func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
       
    let urlinfo = connectionOptions.urlContexts
    let url = urlinfo.first?.url as! NSURL
  
}

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext*h>) {
       
    let url = URLContexts.first!.url as NSURL

}

更新于2021年6月17日

如果你想同时使用Deeplink和Universal Link,这是我的方法。

    //Deeplink or Universial Link Open when app is start.
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
                
        // Universial link Open
        if let userActivity = connectionOptions.userActivities.first,
           userActivity.activityType == NSUserActivityTypeBrowsingWeb,
           let urlinfo = userActivity.webpageURL{
            
            print ("Universial Link Open at SceneDelegate on App Start ::::::: \(urlinfo)")
            
        }
        
        //deeplink Open
        if connectionOptions.urlContexts.first?.url != nil {
          let urlinfo = connectionOptions.urlContexts.first?.url
            
            print ("Deeplink Open at SceneDelegate on App Start ::::::: \(String(describing: urlinfo))")

          
        }
        
        guard let _ = (scene as? UIWindowScene) else { return }
    }

    // Universial link Open when app is onPause
    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
            let urlinfo = userActivity.webpageURL{
            
            print ("Universial Link Open at SceneDelegate on App Pause  ::::::: \(urlinfo)")
            
        }
    }
    
    // Deeplink Open when app in onPause
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        
        let urlinfo = URLContexts.first?.url
        print ("Deeplink Open on SceneDelegate at App Pause :::::::: \(String(describing: urlinfo))")

    }

感谢


2
这个方法在2020年10月对我有效。willConnectTo在应用程序干净启动时被调用,并使用“if let url = connectionOptions.urlContexts.first?.url {....}”适当地获取了深度链接URL。 - Steve B
1
这算是正确答案的一部分,但细节方面还比较简略。稍微补充一下细节:当应用程序在冷启动时启动时,openURLContexts函数将不会被调用,尽管名称暗示它会被调用。您需要检查您的应用程序为什么连接到场景,然后在willConnect函数中执行您在openURLContexts中要执行的操作。 - Chad
1
微小的救星! - Anticro
2
在冷启动通过深度链接时,对我来说connectionOptions.urlContexts.first?.url是空的。 - algrid
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) 是帮助我的。 - Cherpak Evgeny

11

我认为Apple文档解释得最清楚明白,也就是说:

如果您的应用程序选择了场景,并且您的应用程序未运行,则系统会在启动后将URL传递给scene(_:willConnectTo:options:)委托方法,并在您的应用程序在运行或保持暂停状态时传递给scene(_:openURLContexts:).

因此,只有当您的应用程序在运行或保持暂停状态下打开URL时,才会调用您的 scene(_:openURLContexts:)(即问题中具有此签名的函数:func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>))。

相反,当应用程序首次启动时,会调用scene(_:willConnectTo:options:)


2
非常明确的答案,感谢提供文档链接! - floydaddict
很高兴你觉得有帮助! - auspicious99
1
太棒了!但我发现当我的应用程序由URL启动(在此之前该应用程序并未运行)时,在其中一个应用程序中调用了scene(_:openURLContexts:)。我在另一个应用程序中也有相同的代码,但在那种情况下scene(_:openURLContexts:)没有被调用。从我的搜索中,还有其他人观察到了不同的行为。这很奇怪。 - rayx
真的吗?我没有观察到,但也许这可能是iOS中的一个错误?这只发生在某些iOS版本中吗?等等。 - auspicious99
@rayx 是正确的。我有一个应用程序,在其中 openURLContexts 总是被调用,即使应用程序没有启动。在 iOS 16.3 和 15.7.2 上进行了测试。苹果可能已经改变了这种行为吗? - vomi
@auspicious99 很抱歉我回复晚了(我没有收到有关您回复的通知)。我的两个应用程序都安装在运行iOS 16.2的手机上。我能想到的唯一区别是一个应用程序是在XCode 13中创建的,另一个是在XCode 14中创建的,但我不知道这是否重要。从我在网上搜索的结果来看,这似乎不是一个新问题。请参见线程中的最后一篇帖子。 - rayx

8

我曾经遇到了同样的问题,而方法scene(_ scene:, continue userActivity:)只有在应用程序打开时才会被调用。

当我检查传递给方法scene(_ scene:, willConnectTo session, options connectionOptions:)connectionOptions时,它包含了一个带有期望URL的用户活动。因此,我最终手动调用了第一个方法:

func scene(_ scene: UIScene,
           willConnectTo session: UISceneSession,
           options connectionOptions: UIScene.ConnectionOptions) {

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

2
有没有好的解决方案,我遇到了相关问题。Hejazi在这里提出的方法对我没有用。 - Michel

0

我的情况是,从Facebook身份验证返回后,SceneDelegate中提供的openURL额外函数没有被调用。

解决方案是使用:

.onOpenURL { (url) in
                ApplicationDelegate.shared.application(
                    UIApplication.shared,
                    open: url,
                    sourceApplication: nil,
                    annotation: [UIApplication.OpenURLOptionsKey.annotation]
                )
            }

调用我的额外应用程序委托中的函数,然后它正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接