在didFinishLaunchingWithOptions之后几秒钟,应用程序openURL被调用

avi*_*elk 2 deep-linking uiapplicationdelegate ios

我的应用程序具有深层链接功能,在一种情况下也可以正常工作。根据打开应用程序的网址,我有3个不同的入职页面。因此,启动应用程序时,我需要知道是什么链接(如果有)打开了应用程序,然后显示正确的入职页面。问题是我需要知道方法中显示的屏幕:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
Run Code Online (Sandbox Code Playgroud)

但我只能知道深层链接是否在

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation 
Run Code Online (Sandbox Code Playgroud)

在做完之后的5秒didFinishLaunchingWithOptions被调用(我计算了秒数)。所以我有5秒钟的时间才看到一个错误的入职页面,直到openURL调用了l (如果将被调用)。

所以我的问题是:有没有办法知道应用是在URL之前还是期间从URL启动的didFinishLaunchingWithOptions

顺便说一句launchOptionsdidFinishLaunchingWithOptions当应用程序从深层链接打开时为零

Oli*_*ier 6

您要查找的启动选项键是UIApplicationLaunchOptionsURLKey(Objective-C)/ UIApplicationLaunchOptionsKey.url(Swift)。
如果您要定位的是iOS 9及更高版本,则只需拦截来自

  • application:didFinishLaunchingWithOptions: (以防该应用尚未在内存中)
  • application:openURL:options: (以防该应用已在后台运行)。

这是UIApplicationDelegate涵盖两种情况的一种简约实现-请注意,为清楚起见,省略了许多无关的逻辑:

目标C:

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSURL *url = launchOptions[UIApplicationLaunchOptionsURLKey];
    if (url) {
        // TODO: handle URL from here
    }

    return YES;
}

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {

    // TODO: handle URL from here

    return YES;
}

@end
Run Code Online (Sandbox Code Playgroud)

斯威夫特3:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        if let url = launchOptions?[UIApplicationLaunchOptionsKey.url] as? URL {
            // TODO: handle URL from here
        }

        return true
    }

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

        // TODO: handle URL from here

        return true
    }
}
Run Code Online (Sandbox Code Playgroud)


foc*_*ner 6

我刚刚在 iOS 13 中遇到了类似的问题,但在 iOS 13 中情况发生了变化,因为UIWindowSceneDelegate已经被引入并且现在可以完成之前完成的一些工作UIApplicationDelegate(取决于您的应用程序设置)。

@Olivier 在这个线程中的回答对我来说仍然非常有用,因为它指出了处理 URL 方案的两种情况;即当应用程序不在内存中时,调用application:didFinishLaunchingWithOptions:,当应用程序已经加载并在后台时,第二种情况调用application:openURL:options:

因此,正如我上面提到的,如果您使用的是由 XCode 11 生成的默认应用程序模板,那么自 iOS 13 以来的情况会有所不同。我不会在这里详细介绍,所以这里有一个关于该主题的信息丰富的教程:理解iOS 13 场景委托

但是,如果您在场景中使用新方法,需要修改的关键方法是scene(_:willConnectTo:options:)此处的文档)和scene(_:openURLContexts:)此处的文档)。前者是在应用程序尚未加载时对 URL 方案进行操作的位置(因此它有点替换application:didFinishLaunchingWithOptions:),而后者是在调用 URL 方案时应用程序已经在后台时获取 URL 的位置(因此这个代替application:openURL:options:)。

使用scene(_:willConnectTo:options:),您可以查找 URL 方案(如果有)的 URL,执行如下操作:

if let url = connectionOptions.urlContexts.first?.url {
    // handle
}
Run Code Online (Sandbox Code Playgroud)

对于scene(_:openURLContexts:),您可以查看URLContexts集合内部。

我希望这有帮助!