226

On the settings page, I want to include three links to

  • My app support site
  • YouTube app tutorial
  • My primary site (ie: linked to a 'Created by Dale Dietrich' label.)

I've searched this site and the web and my documentation and I've found nothing that is obvious.

NOTE: I don't want to open web pages within my app. I just want to send the link to Safari and that link be open there. I've seen a number of apps doing the same thing in their Settings page, so it must be possible.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dale Dietrich
  • 7,196
  • 4
  • 21
  • 25

15 Answers15

397

Here's what I did:

  1. I created an IBAction in the header .h files as follows:

     - (IBAction)openDaleDietrichDotCom:(id)sender;
    
  2. I added a UIButton on the Settings page containing the text that I want to link to.

  3. I connected the button to IBAction in File Owner appropriately.

  4. Then implement the following:

Objective-C

- (IBAction)openDaleDietrichDotCom:(id)sender {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.daledietrich.com"]];
}

Swift

(IBAction in viewController, rather than header file)

if let link = URL(string: "https://yoursite.com") {
  UIApplication.shared.open(link)
}

Note that we do NOT need to escape string and/or address, like:

let myNormalString = "https://example.com";
let myEscapedString = myNormalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!

In fact, escaping may cause opening to fail.

Top-Master
  • 7,611
  • 5
  • 39
  • 71
Dale Dietrich
  • 7,196
  • 4
  • 21
  • 25
  • 9
    But this is not 100%, because if someone use a jailbreaked iOS and use Chrome or something as default browser, then this will open that, not Safari – Laszlo Sep 30 '13 at 12:55
  • 225
    I feel like if someone's gone to the effort of jailbreaking their phone to make Chrome their default browser, honouring that setting is probably the ideal behaviour. – rpowell Feb 13 '14 at 12:46
  • I understood this but if I am opening a website and user is surfing the website now if he stops by a particular page then can I get the current webpage link in my code? – Varun Jain Jun 01 '16 at 07:33
  • 3
    Above method is deprecated now use following. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:self.advertisement.url] options:@{} completionHandler:^(BOOL success) { }]; – Mashhadi Dec 18 '17 at 14:38
  • @Laszlo Also, in settings we can disable Safari in Restrictions. I coded an app with as URL schemes http and https to open other browsers when an http or https URL is opened and Safari is disabled. So, even without Jailbreak, we can technically change the default web browser. – Emma Labbé Sep 23 '18 at 18:21
172

Swift Syntax:

UIApplication.sharedApplication().openURL(NSURL(string:"http://www.reddit.com/")!)

New Swift Syntax for iOS 9.3 and earlier

As of some new version of Swift (possibly swift 2?), UIApplication.sharedApplication() is now UIApplication.shared (making better use of computed properties I'm guessing). Additionally URL is no longer implicitly convertible to NSURL, must be explicitly converted with as!

UIApplication.sharedApplication.openURL(NSURL(string:"http://www.reddit.com/") as! URL)

New Swift Syntax as of iOS 10.0

The openURL method has been deprecated and replaced with a more versatile method which takes an options object and an asynchronous completion handler as of iOS 10.0

UIApplication.shared.open(NSURL(string:"http://www.reddit.com/")! as URL)
Michael Peterson
  • 10,383
  • 3
  • 54
  • 51
Dustin Williams
  • 3,912
  • 2
  • 16
  • 19
  • 31
    Swift versions of answers are extremely useful to Swift developers, it's a new language without a lot of documentation, esp. on solving real world iOS problems. In my case, autocomplete had chosen the "fileURLWithPath:" selector and I didn't realize that was why my URL was not opening, it was only by reading Dustin's answer that I saw that I should have been using the "string:" selector . So Dustin should be upvoted, not chastised. – SafeFastExpressive Mar 23 '15 at 03:50
  • 3
    @g_fred. Why would he not be able to include a Swift version? – ericgu Mar 24 '15 at 13:21
  • 2
    `openURL(_:)` was deprecated in iOS 10.0, instead you should call the instance method `open(_:options:completionHandler:)` on UIApplication. – Ryan H. Oct 24 '16 at 03:43
  • 2
    You can directly use URL instead of NSURL so you can save the cast. – marsbear Jul 21 '17 at 09:04
  • 1
    I recommend never to force unwrap. ```if let url = NSURL(string:"http://www.reddit.com/") { UIApplication.shared.open(url) }``` will always serve your better. Might want to `assert` and error in the `else` statement to catch typos. – philipp Dec 03 '17 at 00:18
55

Here one check is required that the url going to be open is able to open by device or simulator or not. Because some times (majority in simulator) i found it causes crashes.

Objective-C

NSURL *url = [NSURL URLWithString:@"some url"];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
   [[UIApplication sharedApplication] openURL:url];
}

Swift 2.0

let url : NSURL = NSURL(string: "some url")!
if UIApplication.sharedApplication().canOpenURL(url) {
     UIApplication.sharedApplication().openURL(url)
}

Swift 4.2

guard let url = URL(string: "some url") else {
    return
}
if UIApplication.shared.canOpenURL(url) {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
Chetan Prajapati
  • 2,249
  • 19
  • 24
  • 1
    You can always open HTTP / HTTPS. As of iOS 9, you need to whitelist any URL you wish to call `canOpenURL` on. I don't see why you wouldn't simply call `openURL:url` and if it fails, deal with the failure. `canOpenURL` is primarily used to detect the installation of an app without leaving the current app. – Ben Flynn Apr 25 '16 at 19:57
  • 1
    `openURL(_:)` was deprecated in iOS 10.0, instead you should call the instance method `open(_:options:completionHandler:)` on UIApplication. – Ryan H. Oct 24 '16 at 03:43
21

Take a look at the -openURL: method on UIApplication. It should allow you to pass an NSURL instance to the system, which will determine what app to open it in and launch that application. (Keep in mind you'll probably want to check -canOpenURL: first, just in case the URL can't be handled by apps currently installed on the system - though this is likely not a problem for plain http:// links.)

Tim
  • 59,527
  • 19
  • 156
  • 165
  • Thanks Tim. You are right on point. I was adding my own answer as yours came in. Sorry about that. But at least there is now an easy how-to for those that follow me. – Dale Dietrich Sep 14 '12 at 00:09
  • No worries - glad you found the solution! – Tim Sep 14 '12 at 00:11
  • 1
    `openURL(_:)` was deprecated in iOS 10.0, instead you should call the instance method `open(_:options:completionHandler:)` on UIApplication. – Ryan H. Oct 24 '16 at 03:43
17

And, in case you're not sure if the supplied URL text has a scheme:

NSString* text = @"www.apple.com";
NSURL*    url  = [[NSURL alloc] initWithString:text];

if (url.scheme.length == 0)
{
    text = [@"http://" stringByAppendingString:text];
    url  = [[NSURL alloc] initWithString:text];
}

[[UIApplication sharedApplication] openURL:url];
meaning-matters
  • 21,929
  • 10
  • 82
  • 142
16

The non deprecated Objective-C version would be:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://apple.com"] options:@{} completionHandler:nil];
Antzi
  • 12,831
  • 7
  • 48
  • 74
11

Swift 3 Solution with a Done button

Don't forget to import SafariServices

if let url = URL(string: "http://www.yoururl.com/") {
            let vc = SFSafariViewController(url: url, entersReaderIfAvailable: true)
            present(vc, animated: true)
        }
Baher A
  • 117
  • 1
  • 5
  • This is the perfect answer which works in both iOS and iOS Extensions. Other answers only work in apps and can't be used in extensions. – Owen Zhao Jun 05 '19 at 08:22
10

Swift 3.0

if let url = URL(string: "https://www.reddit.com") {
    if #available(iOS 10.0, *) {
        UIApplication.shared.open(url, options: [:])
    } else {
        UIApplication.shared.openURL(url)
    }
}

This supports devices running older versions of iOS as well

Greg T
  • 3,278
  • 3
  • 37
  • 39
5

Because this answer is deprecated since iOS 10.0, a better answer would be:

if #available(iOS 10.0, *) {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}else{
    UIApplication.shared.openURL(url)
}

y en Objective-c

[[UIApplication sharedApplication] openURL:@"url string" options:@{} completionHandler:^(BOOL success) {
        if (success) {
            NSLog(@"Opened url");
        }
    }];
Diego Jiménez
  • 1,398
  • 1
  • 15
  • 26
4

Swift 5:

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)")
     }
   }
 }

Usage:

open(scheme: "http://www.bing.com")

Reference:

OpenURL in iOS10

Zgpeace
  • 3,927
  • 33
  • 31
3

openURL(:) was deprecated in iOS 10.0, instead you should use the following instance method on UIApplication: open(:options:completionHandler:)

Example using Swift
This will open "https://apple.com" in Safari.

if let url = URL(string: "https://apple.com") {
    if UIApplication.shared.canOpenURL(url) {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }
}

https://developer.apple.com/reference/uikit/uiapplication/1648685-open

Ryan H.
  • 2,543
  • 1
  • 15
  • 24
2

In SWIFT 3.0

               if let url = URL(string: "https://www.google.com") {
                 UIApplication.shared.open(url, options: [:])
               }
OurangZeb Khan
  • 1,114
  • 18
  • 20
1

Try this:

NSString *URL = @"xyz.com";
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:URL]])
{
     [[UIApplication sharedApplication] openURL:[NSURL URLWithString:URL]];
}
arghtype
  • 4,376
  • 11
  • 45
  • 60
Shubham JAin
  • 593
  • 8
  • 15
0

In Swift 1.2, try this:

let pth = "http://www.google.com"
    if let url = NSURL(string: pth){
        UIApplication.sharedApplication().openURL(url)
aircraft
  • 25,146
  • 28
  • 91
  • 166
Dilip Tiwari
  • 1,441
  • 18
  • 31
-2

Swift 4 solution:

UIApplication.shared.open(NSURL(string:"http://yo.lo")! as URL, options: [String : Any](), completionHandler: nil)
Kevin ABRIOUX
  • 16,507
  • 12
  • 93
  • 99
  • 1
    A proper Swift 4 version would use URL and not NSURL. And casting NSURL as URL is not the same. See stackoverflow.com/a/37812485/2227743 for an explanation. Also, force unwrapping is bad. – Eric Aya Oct 30 '17 at 13:45