【问题标题】:How do I tell if the app is launched from a URL scheme or a normal launch?如何判断应用程序是从 URL 方案启动还是正常启动?
【发布时间】:2014-01-18 19:45:46
【问题描述】:

基本上,每当应用程序启动或打开时,我都会检查剪贴板上是否有链接,如果有,我会询问用户是否要添加它。

但是,我最近添加了使用 x-callback-urls 将 URL 添加到应用程序中的功能。如果他们使用 LaunchPad 之类的应用在我的应用中打开 URL,“你想从剪贴板添加 URL 吗?”通知仍然打开,这没有多大意义,因为他们已经启动它以添加该 URL。

问题是,我的 AppDelegate 中的 openURL: 方法被调用来处理 URL 方案 之后 appDidFinishLaunchingappWillEnterForeground,所以我无法检查这些以查看是否openURL 方法已被调用。我可以使用dispatch_after,但这似乎很懒惰和hacky。

有没有办法检查应用的启动方式,即:通过 URL 方案或通过手动打开?

【问题讨论】:

    标签: ios objective-c x-callback-url


    【解决方案1】:

    不要实现applicationDidFinishLaunching:。请改用application:didFinishLaunchingWithOptions:。同样不要使用application:handleOpenURL:,而是使用application:openURL:sourceApplication:annotation:

    如果您从 URL 启动,则选项字典将包含 UIApplicationLaunchOptionsURLKey 键,该键的值将是 URL。

    但是,如果您的应用程序已经在运行但在后台,并且用户调用了重新打开您的应用程序的 URL,您将收到 application:openURL:sourceApplication:annotation: 消息。 你真正需要做的是实现一个handleURL 方法,然后从application:didFinishLaunchingWithOptions:application:openURL:sourceApplication:annotation: 调用该方法

    编辑:

    请注意,在 iOS 9 中,Apple 弃用了 application:openURL:sourceApplication:annotation: 并添加了新方法 application:openURL:options:

    如果您的应用仅适用于 iOS 9 及更高版本,则应实现新的 application:openURL:options: 方法。如果您需要支持 iOS 9 更早的版本,您可能应该同时实现 application:openURL:sourceApplication:annotation: 和新的 iOS 9 方法 application:openURL:options:。操作系统将为您正在运行的操作系统版本调用正确的版本。然后,我将创建一个两者都调用的通用方法。这样你就可以从两个操作系统版本中调用,但你处理打开 URL 的代码只在一个地方。

    【讨论】:

    • 查看此答案以了解如何使用 Swift 3 引用 UIApplicationLaunchOptionsURLKeystackoverflow.com/a/26649321/144088
    • 根据我们的测试,如果用户从 URL 启动,即使应用程序尚未运行,application:openURL:options 似乎也会被调用。
    【解决方案2】:

    applicationDidBecomeActiveopenURLcontinueUserActivity 之后调用(以及在appWillEnterForeground 之后),因此是确定应用程序打开方式的好地方。

    缓存openURLcontinueUserActivity中的url(取决于来源,深层链接可能来自continueUserActivity。有趣的是,我总是看到从Messages打开链接时调用了该方法。然后检查@中的url 987654328@

      private var launchURL:URL?
    
      static func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
        launchURL = userActivity.webpageURL
        // Do something with userActivity
        return true
      }
    
      static func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
        launchURL = url
        // Do something with URL
        return true
      }
    
      static func applicationDidBecomeActive(_ application: UIApplication) {
        defer {
          launchURL = nil // Just cleaning up
        }
    
        let didLaunchFromURL = launchURL != nil
      }
    
    

    【讨论】:

    • 我看到在使用断点打开 url 之前调用了 didBecomeActive。
    • @Kevin, @Amber K: didBecomeActive 可能比continueUserActivity 更早出现在应用程序已经在屏幕上并使用响应应用程序的 URL 执行扫描 NFC 标签的情况下(通过 applinks技术)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多