18

I am having trouble figuring out how to switch to Safari from a native app in iOS 7+. I've used UIApplication.sharedApplication.openURL(), but that opens a new tab. I would like to return the user to the current page he/she was viewing before without opening a new tab. I found this SO post, but it is a few years old, so I was hoping things have changed since then.

Here is the workflow I am envisioning:

  1. User taps on a link on an HTML page on Safari to open/install my app
  2. User performs an action on my app
  3. After the user is done performing the action, my app opens Safari automatically, and the user is back on the page where he/she left off

Google has somehow done this with their Google Maps app. If you search for an address on google.com on Safari, you can tap on the map that appears in the search results, and it will open the Maps app. At the top of the Maps app will be a "Return to Safari" bar that you can tap. Once you tap it, you are returned to Safari without loading another tab. I can't seem to find anything regarding how Google did this. If I can replicate that behavior in my app, that would work just fine.

Any help would be greatly appreciated!

Community
  • 1
  • 1
Alexander
  • 3,959
  • 2
  • 31
  • 58

2 Answers2

14

There is a way to accomplish what you want using standard iOS APIs. No need to use external components.

You control your webpage and your app, so you know the exact URL that has the link to your app.

These are the steps:

1) In your app, define a custom URL scheme. In this case let's assume you use the scheme myawesomeapp://. You can do this in your Xcode project by going to the Info section of your target. See below

Defining a custom URL scheme

2) In your web page you need to handle the two scenarios: app installed / not installed. It is just a matter of detecting if an app responds to the scheme myawesomeapp://.

To detect from your webpage if your app is not installed please refer to this post

I will explain the case where your app is already installed.

Let's say the webpage that contains the link is:

http://www.mywebsite.com/mypage.html#mytag

The link you provide in your webpage should pass some parameters to the app and one of these should be the URL that you want the app to return. Following with the example the link could be:

myawesomeapp://?action=my_action_1&sourceurl=http%3A%2F%2Fwww.mywebsite.com%2Fmypage.html%23mytag

Note that the URL you pass as a parameter inside the scheme has to be URL encoded or it won't work properly.

3) In your app delegate you need to implement the method:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

In this method, parse the URL, decode the query items and pass the sourceURL to the view controller responsible of handling the action prior to calling it. In this case I set a public property in the ViewController that will store the URL.

@property (nonatomic, strong) NSURL *sourceURL;

4) In the view controller when the user finishes the interaction, you just call:

[[UIApplication sharedApplication] openURL:self.sourceURL];

Because self.sourceURL contains the URL of your webpage, Safari will be launched with the URL. However, because that page is already opened, iOS detects this and re-opens that page.

I have a sample project in my Github page that implements all this.

And to finalize, after you install the sample project in your iPhone, open this stack overflow post from mobile Safari and open my awesome app

Once the app is opened, click on the button and you will return to this stack overflow post.

Community
  • 1
  • 1
Juan Catalan
  • 2,299
  • 1
  • 17
  • 23
  • 2
    Wow, thank you for the amazing and thorough response!! I will take another look at this answer and give it a try on Tuesday! – Alexander May 25 '15 at 04:23
  • @Alexander let me know if you need some help with the Github project. – Juan Catalan May 25 '15 at 15:15
  • 1
    Awesome, I got it working! Thank you very much for your detailed answer and the sample code! Is there any way to prevent Safari from reloading the page after it opens the existing tab? – Alexander May 26 '15 at 15:09
  • @Alexander If the page is cached it won't reload. Unfortunately you can't control this. However I have used this approach in some of my apps and does the job. – Juan Catalan May 26 '15 at 15:51
  • @JuanCatalan link[5] would need to be updated with https, since this is the default protocol for SO now. I have added one myself here: http://nub.ro/testiosurlopen – marosoaie Mar 03 '21 at 11:59
3

The behaviour you described is exactly what FB's AppLinks is designed for, and you'll get the same behaviour with all iOS apps that support it (which is quite a lot) out of box!

By the way Google Maps uses the same component: you can see it if you open Google Maps from let's say Fantastical.app! enter image description here

Sash Zats
  • 5,376
  • 2
  • 28
  • 42