Question

Basically, whenever the app launches or opens I have a check to see if there's a link on the clipboard, and if so I ask the user if he/she wants to add it.

However, I recently added the ability to use x-callback-urls to add URLs into the app. If they use an app like LaunchPad to open a URL in my app, the "do you want to add the URL from your clipboard?" notification still opens, which doesn't make much sense as they've already launched it to add that URL.

Problem is, the openURL: method in my AppDelegate is called to handle the URL scheme after appDidFinishLaunching and appWillEnterForeground, so I can't put a check in those to see if the openURL method was already called. I could use a dispatch_after, but that seems lazy and hacky.

Is there a way to check how the app was launched, i.e.: via a URL scheme or via a manual open?

No correct solution

OTHER TIPS

Don't implement applicationDidFinishLaunching:. Use application:didFinishLaunchingWithOptions: instead. Likewise don't use application:handleOpenURL:, use application:openURL:sourceApplication:annotation: instead.

If you are launched from a URL the options dictionary will contain a UIApplicationLaunchOptionsURLKey key, and the value for that key will be the URL.

However, if your app is already running but is in the background and the user invokes a URL that re-opens your app, you will get a application:openURL:sourceApplication:annotation: message instead. What you really need to do is implement a handleURL method, and then call that method from both application:didFinishLaunchingWithOptions: and application:openURL:sourceApplication:annotation:

EDIT:

Note that in iOS 9, Apple deprecated application:openURL:sourceApplication:annotation: and added the new method application:openURL:options:.

If your app is iOS 9 and later only, you should implement the new application:openURL:options: method. If you need to support iOS 9 and earlier versions, you should probably implement both application:openURL:sourceApplication:annotation: and the new iOS 9 method application:openURL:options:. The OS will call the correct version for the OS version you are running. I would then create a common method that both of those call. That way you get called from both OS versions, but your code to handle opening an URL is only in one place.

applicationDidBecomeActive is called after openURL and continueUserActivity (and after appWillEnterForeground), so is a good place to determine how the app was opened.

Cache the url in openURL and continueUserActivity (depending on the source, deep links may come from continueUserActivity. Anecdotally, I always see that method called when opening a link from Messages. Then check that url in applicationDidBecomeActive

  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
  }

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top