深度链接URL方案在iOS应用委托中没有调用任何功能

14

我正在iOS中实现深度链接。我已经在项目设置-信息-URL类型中配置了URL Scheme。

URL Schemes: carwash role:Viewer

当我输入carwash://something时,浏览器要求打开应用程序,但是没有调用我处理的应用程序的任何内容。

Apple文档说你应该在AppDelegate中覆盖application(open url),但是深度链接没有调用它,而应用程序会以最后一个状态打开。

'application:openURL:options:' 没有被调用。

这是我的代码,但不起作用。

func application(_ app: UIApplication, open url: URL,
                     options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    fatalError()
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    if let url = launchOptions?[UIApplication.LaunchOptionsKey.url] as? URL {
        /// some
        fatalError()
    }
    GMSServices.provideAPIKey("")

    return true
}

你需要在你的“打开URL”委托方法中返回true - Starsky
这个回答解决了你的问题吗?方法'application:openURL:options:'没有被调用 - Hejazi
5个回答

14
在iOS 13中,UIApplication application(_:open:options:)没有被调用(至少在我的情况下可能是如此)。您应该覆盖下面的SceneDelegate函数:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let url = URLContexts.first?.url{
        print(url) 
    }
}

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // detect the URLContext in the `options:` and deal with it.
}

如果用户在您的应用程序未运行时点击链接,则不会调用scene(_: openURLContexts:),但将调用scene(_:willConnectTo:options:)


2
只对了一半。如果 URL 在您的应用程序未运行时到达,那么它将无法工作。 - matt
那你有什么建议? - Arvin Rezaei
2
这不是我“建议”的问题,而是事实。你必须实现scene(_:willConnectTo:options:)来检测options:中的URLContext并处理它。否则,如果用户在您的应用程序未运行时点击链接,您将无法对其做出响应。试一试,你就会明白。 - matt
2
谢谢你的帮助,Crystal Sphere Matt。你的评论真的很有用。 - kironet

2
在iOS 13+或场景代理中,会调用两个方法,并且一定会调用willPerformHTTPRedirection方法。
  func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url =      userActivity.webpageURL {
          
        }
      }
    }

 func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Swift.Void) {
            if let url = request.url {
               guard let detailDictionary = String.queryParameters(from: url) else { return }

            }
        }
    }

使用这个函数解析url:

static func queryParameters(from url: URL) -> [String: String]? {
    let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)
    var queryParams: [String : String]? = nil
    if let components = urlComponents?.queryItems {
      queryParams = [String: String]()
      for queryItem in components {
        if queryItem.value == nil {
          continue
        }
        queryParams?[queryItem.name] = queryItem.value
      }
    }
    return queryParams
  }

1
queryParameters 对我在 Firebase 的新版本中非常有帮助。 - Niraj

0

对于我而言,在iOS13及以上版本中,以下代码可行(在我的SceneDelegate文件中):

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Set up everything you need
    // ...
    
    // Handle deep link on cold start
    if let url = connectionOptions.userActivities.first?.webpageURL {
        handle(url: url)
    }
}

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    if let url = userActivity.webpageURL {
        // Handle deep link when the app is running
        handle(url: url)
    }
}

0

关于编程方面,你应该使用 application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool

请注意,你的方法中没有返回语句

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    print("Got from URL: \(url)"
    return true
}

模拟器中的链接最好通过终端完成

xcrun simctl openurl booted “carwasher://deeplink”

1
谢谢您的回答。我复制了您的代码,但应用程序通过深链接打开,但该函数没有被调用,也没有任何内容被打印出来。 - Arvin Rezaei
请尝试从“查看者”更改到“编辑者”在“信息”选项卡中的角色。 - Iliya Kisliy

-1

您应该在 Info.plist 文件中配置深度链接

示例:

<key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>CFBundleURLName</key>
            <string>carwash</string> // your identifier
            <key>CFBundleURLSchemes</key>
            <array>
                <string>carwash</string> // schema
            </array>
        </dict>
    </array>

1
它已经被声明。我可以通过深链接打开应用程序,但是我无法处理它。 - Arvin Rezaei

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