如何在处理通用 link 之前等待 didFinishLaunchingWithOptions 完成?
How to wait for didFinishLaunchingWithOptions to finish before handling universal link?
在我的 Swift iOS 应用程序中,我在 didFinishLaunchingWithOptions
内的 AppDelegate
中异步设置了初始视图控制器。现在我要添加一个通用 Link,这样如果您在 phone 上转到相应的 URL,它将自动打开应用程序中的正确页面(在本例中是密码重置URL 如果正确,将在应用内打开密码重设表单。
我正在 AppDelegate
.
中处理 application(_:continue:restorationHandler:)
(continueUserActivity
) 中的 linking
如果应用程序已经 运行 则它可以工作,否则 link 处理发生在我的应用程序完成设置初始视图控制器和深层视图控制器之前 link在 didFinishLaunchingWithOptions
returns.
时被解雇
如何确保应用程序在我从 continueUserActivity
显示视图控制器之前完成设置?我不能't/shouldn阻止didFinishLaunching
返回,直到视图控制器被设置,所以方法returns出现在初始视图控制器之前。
我知道我可以检查 didFinishLaunchingWithOptions
中的用户 activity 字典,但 continueUserActivity
仍然被调用(如果仅在应用程序是 运行,就像 didReceiveRemoteNotification
的工作原理一样)。是否有条件检查此方法内部以将 link 处理推迟到 didFinishLaunching
?
一些简化的UIApplicationDelegate
代码来帮助解释:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
doSomeAsyncSetup(
completion: {
presentSomeViewController()
}
)
return true
}
func application(_: UIApplication, continue userActivity: NSUserActivity, restorationHandler _: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
let params = components.queryItems,
components.path == pathThatIExpect
{
handleUniversalLink(params)
}
return true
}
请注意,当应用程序选择 Scenes
但我的应用程序未使用它时,区别似乎略有不同 (https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app)。
您可以为此使用串行队列。例如:
serialQueue.async {
self.presentSomeViewController()
}
和
serialQueue.async {
self.handleUniversalLink(params)
}
DispatchGroup
应该可以为您处理。
private let dispatchGroup = DispatchGroup()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.dispatchGroup.enter()
doSomeAsyncSetup(
completion: {
presentSomeViewController()
self.dispatchGroup.leave()
}
)
return true
}
func application(_: UIApplication, continue userActivity: NSUserActivity, restorationHandler _: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
let params = components.queryItems,
components.path == pathThatIExpect
{
self.dispatchGroup.notify {
handleUniversalLink(params)
}
}
return true
}
在启动您的应用程序的情况下,在 didFinishLaunching
中输入调度组,并在呈现视图控制器后将其保留。
一旦调度组为空,notify
将执行用户activity代码;所以只有在你的视图控制器出现之后。
如果您的应用已经启动,调度组将为空,因为 didFinishLaunching
未被调用,因此 notify
将立即执行
在我的 Swift iOS 应用程序中,我在 didFinishLaunchingWithOptions
内的 AppDelegate
中异步设置了初始视图控制器。现在我要添加一个通用 Link,这样如果您在 phone 上转到相应的 URL,它将自动打开应用程序中的正确页面(在本例中是密码重置URL 如果正确,将在应用内打开密码重设表单。
我正在 AppDelegate
.
application(_:continue:restorationHandler:)
(continueUserActivity
) 中的 linking
如果应用程序已经 运行 则它可以工作,否则 link 处理发生在我的应用程序完成设置初始视图控制器和深层视图控制器之前 link在 didFinishLaunchingWithOptions
returns.
如何确保应用程序在我从 continueUserActivity
显示视图控制器之前完成设置?我不能't/shouldn阻止didFinishLaunching
返回,直到视图控制器被设置,所以方法returns出现在初始视图控制器之前。
我知道我可以检查 didFinishLaunchingWithOptions
中的用户 activity 字典,但 continueUserActivity
仍然被调用(如果仅在应用程序是 运行,就像 didReceiveRemoteNotification
的工作原理一样)。是否有条件检查此方法内部以将 link 处理推迟到 didFinishLaunching
?
一些简化的UIApplicationDelegate
代码来帮助解释:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
doSomeAsyncSetup(
completion: {
presentSomeViewController()
}
)
return true
}
func application(_: UIApplication, continue userActivity: NSUserActivity, restorationHandler _: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
let params = components.queryItems,
components.path == pathThatIExpect
{
handleUniversalLink(params)
}
return true
}
请注意,当应用程序选择 Scenes
但我的应用程序未使用它时,区别似乎略有不同 (https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app)。
您可以为此使用串行队列。例如:
serialQueue.async {
self.presentSomeViewController()
}
和
serialQueue.async {
self.handleUniversalLink(params)
}
DispatchGroup
应该可以为您处理。
private let dispatchGroup = DispatchGroup()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.dispatchGroup.enter()
doSomeAsyncSetup(
completion: {
presentSomeViewController()
self.dispatchGroup.leave()
}
)
return true
}
func application(_: UIApplication, continue userActivity: NSUserActivity, restorationHandler _: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
let params = components.queryItems,
components.path == pathThatIExpect
{
self.dispatchGroup.notify {
handleUniversalLink(params)
}
}
return true
}
在启动您的应用程序的情况下,在 didFinishLaunching
中输入调度组,并在呈现视图控制器后将其保留。
一旦调度组为空,notify
将执行用户activity代码;所以只有在你的视图控制器出现之后。
如果您的应用已经启动,调度组将为空,因为 didFinishLaunching
未被调用,因此 notify
将立即执行