91

Apple with iOS 10 has deprecated openURL: for openURL:option:completionHandler If I have:

 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.google.com"]];

How it will become? options:<#(nonnull NSDictionary<NSString *,id> *)#> in detail

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.google.com"] options:<#(nonnull NSDictionary<NSString *,id> *)#> completionHandler:nil];

Thanks

Update options:@{} For empty dictionary with no key and value http://useyourloaf.com/blog/querying-url-schemes-with-canopenurl/

Joannes
  • 2,569
  • 3
  • 17
  • 39
  • 1
    The options dictionary is described in both answers [here](http://stackoverflow.com/questions/38964264/openurl-in-ios10). – Dev Sanghani Sep 17 '16 at 14:45
  • 3
    BTW - If your app still support iOS 9 or lower, just keep using the old `openURL`. You should only move to the new one if your Deployment Target is iOS 10. – rmaddy Sep 17 '16 at 14:48
  • obviously in UIKit.framework this is commented! – Joannes Sep 29 '16 at 13:21
  • Possible duplicate of [OpenURL in iOS10](http://stackoverflow.com/questions/38964264/openurl-in-ios10) – KSigWyatt Jan 24 '17 at 21:50

6 Answers6

166

Write like this.

Handle completionHandler

UIApplication *application = [UIApplication sharedApplication];
NSURL *URL = [NSURL URLWithString:@"http://www.google.com"];
[application openURL:URL options:@{} completionHandler:^(BOOL success) {
    if (success) {
         NSLog(@"Opened url");
    }
}];

Without handling completionHandler

[application openURL:URL options:@{} completionHandler:nil];

Swift Equivalent:- open(_:options:completionHandler:)

UIApplication.shared.open(url)
Nirav D
  • 71,513
  • 12
  • 161
  • 183
  • 1
    Check this tutorial for more detail http://useyourloaf.com/blog/querying-url-schemes-with-canopenurl/ – Nirav D Sep 17 '16 at 14:51
  • 1
    @{} for what use? – Joannes Sep 17 '16 at 15:00
  • 2
    For empty dictionary with no key and value. – Nirav D Sep 17 '16 at 15:01
  • In keyboard extension and iOS10 without shared Application how you can do it? – Learn Swift Nov 04 '16 at 15:13
  • Hi @NiravD I am trying to open a URL in wkwebview. How do i achieve the same without using openURL? openURL uses browser, i am trying to open a url within my application using webkit. – iPhoneDeveloper Dec 22 '17 at 12:12
  • @iPhoneKar You need to make `NSURLRequest` from `URL` and then need to call [`loadRequest`](https://developer.apple.com/documentation/webkit/wkwebview/1414954-loadrequest?language=objc) method on you `WKWebView` object. – Nirav D Dec 22 '17 at 14:02
19

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.

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:

  • The URL to open
  • An options dictionary (see below for valid entries). Use an empty dictionary for the same behaviour as openURL:.
  • A completion handler called on the main queue with the success. Nullable if you are not interested in the status.

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 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:

  • UIApplicationOpenURLOptionUniversalLinksOnly: Use a boolean value set to true (YES) to only open the URL if it is a valid universal link with an application configured to open it. If there is no application configured or the user disabled using it to open the link the completion handler is called with false (NO).

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.

Refrence : openURL: deprecated in iOS 10

Mihir Oza
  • 2,768
  • 3
  • 35
  • 61
Disha
  • 608
  • 7
  • 10
12

// Objective-C

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

// Swift

  UIApplication.shared.open(url, options: [:], completionHandler: nil)
  • You can even omit options and completionHandler parameters because they are initialised by default to [:] and nil values respectively. Just keep UIApplication.shared.open(url) – Sanjeevcn Feb 27 '20 at 10:17
6

Swift 5.0.1 and above

UIApplication.shared.open(URL.init(string: UIApplication.openSettingsURLString)!)
vikas kumar
  • 10,447
  • 2
  • 46
  • 52
3
 // In Xcode 9 and iOS 11

  UIApplication *application = [UIApplication sharedApplication];
    NSURL *URL = [NSURL URLWithString:@"http://facebook.com"];
    [application openURL:URL options:@{} completionHandler:^(BOOL success) {
        if (success) {
            NSLog(@"Opened url");
        }
    }];
0

Open Application Setting (Objective-c)

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]
                                           options:@{}
                                 completionHandler:^(BOOL success) {
        }];
  • Tested in iOS 12
Community
  • 1
  • 1
Vivek
  • 4,916
  • 35
  • 40