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

iPh*_*one 19 iphone custom-scheme-url swift5 ios13

在 info.plist 文件中,我配置URL IdentifierURL Scheme成功。我也可以使用自定义 URL 打开应用程序。问题是当应用程序第一次启动该方法时

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) 
Run Code Online (Sandbox Code Playgroud)

不叫。

我有一些基于上述方法的依赖功能。所以当应用程序第一次启动时,我在我的应用程序中看不到任何东西。

我还在方法中添加了代码

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

但我在这里得到的 url 为零。

但是,如果我的应用程序处于后台模式并且我点击了 URL,那么上述方法调用成功并且相关功能正常工作。以下是我scene(_:openURLContexts:)sceneDelegate.

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()
    }
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*rks 16

也许这会对你的情况有所帮助。


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

}

Run Code Online (Sandbox Code Playgroud)

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))")

    }
Run Code Online (Sandbox Code Playgroud)

谢谢

  • 对我来说,通过深层链接冷启动时,connectionOptions.urlContexts.first?.url 为零。 (3认同)
  • 这在 2020 年 10 月对我有用。 willConnectTo 在干净的应用程序启动时被调用,并使用“ if let url = connectionOptions.urlContexts.first?.url {....” 正确地为我提供了深层链接 URL (2认同)

aus*_*s99 11

我认为苹果文档解释得最清楚,即

如果您的应用程序已选择加入场景,并且您的应用程序未运行,则系统会scene(_:willConnectTo:options:)在启动后将 URL 传递给委托方法,以及scene(_:openURLContexts:)当您的应用程序在内存中运行或暂停时打开 URL 时。

因此,当您的应用程序在运行或仅在内存中暂停时打开 URL 时,它只会调用您的scene(_:openURLContexts:)(即具有此签名的:func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>)在问题中)。

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

  • 显然是最好的答案,感谢您提供文档链接! (2认同)
  • 很好的答案!但我发现当我的一个应用程序通过 URL 启动时,会调用 `scene(_:openURLContexts:)` (该应用程序在此之前并未运行)。我在另一个应用程序中有相同的代码,但在这种情况下不会调用 `scene(_:openURLContexts:)` 。根据我的搜索,还有其他人也观察到了不同的行为。有点奇怪。 (2认同)

Hej*_*azi 8

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

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

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

    if let userActivity = connectionOptions.userActivities.first {
        self.scene(scene, continue: userActivity)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 有没有好的解决方案,我面临着一个相关问题。Hejazi 在这里建议的方法对我不起作用。 (2认同)