openURL Deprecated in iOS10

Apple introduced the openURL: method as a way to open external links with iOS 2. The related function canOpenURL: got some privacy controls in iOS 9 to stop you from querying devices for installed apps. Now with iOS 10 Apple has deprecated the plain old openURL for openURL:options:completionHandler:. Here is my quick guide to what you need to know to open an external link with iOS 10.

What’s New in iOS 10

From Apple’s guide to What’s New in iOS in the section on UIKit:

The new UIApplication method openURL:options:completionHandler:, which is executed asynchronously and calls the specified completion handler on the main queue (this method replaces openURL:).

The now deprecated method has a single parameter for the URL to open and returns a boolean to report success or failure:

// Objective-C
- (BOOL)openURL:(NSURL*)url

// Swift
open func canOpenURL(_ url: URL) -> Bool

The new method in iOS 10:

// Objective-C
- (void)openURL:(NSURL*)url options:(NSDictionary<NSString *, id> *)options
  completionHandler:(void (^ __nullable)(BOOL success))completion

// Swift
open func open(_ url: URL, options: [String : Any] = [:],
  completionHandler completion: (@escaping (Bool) -> Swift.Void)? = nil)

There are now three parameters:

Opening a URL with iOS 10

What does this mean if you have an iOS 10 only app, don’t care about options and completion status and just want to stop Xcode complaining:

// Objective-C
UIApplication *application = [UIApplication sharedApplication];
[application openURL:URL options:@{} completionHandler:nil];

// Swift
UIApplication.shared.open(url, options: [:], completionHandler: nil)

In practise as long as you are still supporting iOS 9 or earlier you will want to fallback to the plain old openURL method. Let’s look at an example where we do that and also use the completion handler to check the status of the open:

First with Objective-C:

- (void)openScheme:(NSString *)scheme {
  UIApplication *application = [UIApplication sharedApplication];
  NSURL *URL = [NSURL URLWithString:scheme];

  if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
    [application openURL:URL options:@{}
       completionHandler:^(BOOL success) {
      NSLog(@"Open %@: %d",scheme,success);
    }];
  } else {
    BOOL success = [application openURL:URL];
    NSLog(@"Open %@: %d",scheme,success);
  }
}

// Typical usage
[self openScheme:@"tweetbot://timeline"];

I am passing an empty dictionary for the options and I don’t do anything useful in the completion handler other than log the success. The Swift version:

func open(scheme: String) {
  if let url = URL(string: scheme) {
    if #available(iOS 10, *) {
      UIApplication.shared.open(url, options: [:],
        completionHandler: {
          (success) in
           print("Open \(scheme): \(success)")
       })
    } else {
      let success = UIApplication.shared.openURL(url)
      print("Open \(scheme): \(success)")
    }
  }
}

// Typical usage
open(scheme: "tweetbot://timeline")

Options

The UIApplication header file lists a single key for the options dictionary:

To override the default behaviour create a dictionary with the key set to true (YES) and pass it as the options parameter:

// Objective-C
NSDictionary *options = @{UIApplicationOpenURLOptionUniversalLinksOnly : @YES};
[application openURL:URL options:options completionHandler:nil];

// Swift
let options = [UIApplicationOpenURLOptionUniversalLinksOnly : true]
UIApplication.shared.open(url, options: options, completionHandler: nil)

So for example if I set this to true and try to open the URL https://twitter.com/kharrison it will fail if I do not have the Twitter app installed instead of opening the link in Safari (thanks to Kamil for clarifying in the comments below).

Further Reading

Never miss a post!

iOS Size Classes Cheat Sheet

Subscribe and get my free iOS Size Classes Cheat Sheet

Success! Now check your email to confirm your subscription and download your free guide to iOS Size Classes.

There was an error submitting your subscription. Please try again.

Unsubscribe at any time.
No time to watch WWDC videos?

Sign up to get my iOS posts direct to your inbox and I will send you a free PDF of my iOS Size Classes Cheat Sheet.

OK! Check your inbox (or spam folder) for an email to confirm your details and download your free guide to iOS Size Classes.

There was an error submitting your subscription. Please try again.

Unsubscribe at any time.
Archives Categories