【问题标题】:Method 'scene(_:openURLContexts:)' is not called未调用方法“场景(_:openURLContexts :)”
【发布时间】:2020-03-17 06:43:57
【问题描述】:

在 info.plist 文件中我成功配置了URL Identifier 和URL 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()
    }

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

【问题讨论】:

  • 这个问题的当前状态是什么?其中一个答案是否解决了您的问题?如果是,请接受其中之一。您需要更多帮助吗?如果是,您能否解释所提供的解决方案对您的问题做了什么以及仍然缺少什么?我很乐意帮助你解决这个问题

标签: iphone ios13 swift5 custom-scheme-url


【解决方案1】:

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


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

}

17.6.2021 更新

如果您想同时使用 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))")

    }

谢谢

【讨论】:

  • 这在 2020 年 10 月对我有用。将在干净的应用程序启动时调用 willConnectTo 并使用“if let url = connectionOptions.urlContexts.first?.url {....”让我获得了正确的深层链接 URL
  • 这是一个正确的答案,但非常注重细节。稍微填写一下细节:当应用程序在冷启动时启动时,openURLContexts 函数将不会被调用,即使名称暗示它会。您需要检查您的应用连接到场景的原因,然后执行您在 willConnect 函数的 openURLContexts 中执行的操作。
  • 小小的救命稻草! ?
  • 对我来说 connectionOptions.urlContexts.first?.url 在冷启动时通过深层链接为零。
  • func scene(_ scene: UIScene, continue userActivity: NSUserActivity) 对我有帮助
【解决方案2】:

我遇到了同样的问题,方法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)
    }
}

【讨论】:

  • 有没有好的解决方案,我面临一个相关的问题。 Hejazi 在这里建议的方法对我不起作用。
【解决方案3】:

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

解决方案正在使用

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

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

【讨论】:

    【解决方案4】:

    我认为the Apple docs解释得最清楚,即,

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-21
      相关资源
      最近更新 更多