2

How to avoid an UIWebView from opening the iTunes App when loading an iTunes URL?

Example URL: http://itunes.apple.com/nl/app/bluppr-postcards/id348147229?mt=8

Above URL loads the iTunes App directly. UIWebViewDelegate doesn't seem to be able to control this to just load the page in the UIWebView.

It seems it's controlled by the JavaScript function detectAndOpenItunes(); in the body tag of the page.

Any ideas?

Ben Groot
  • 5,040
  • 3
  • 40
  • 47
  • 1
    So you want the HTML version to open — blocking the entire URL isn't acceptable? Have you checked whether your web view delegate gets offered webView:shouldStartLoadWithRequest:navigationType: for a custom iTunes URL scheme after all the http stuff is done? – Tommy May 27 '11 at 11:14
  • Hi Tommy, thanks for your comment. Yes, I want the HTML version to load, so the user will stay in the App. The shouldStartLoadWithRequest is returning an itms-apps scheme after the html scheme. If I return NO in shouldStartLoadWithRequest on the itms-apps scheme then it is not loading anything and returns in didFailLoadWithError. Do you have any suggestions? – Ben Groot Jun 06 '11 at 08:38

1 Answers1

5

You're right that the relevant function is detectAndOpenItunes(), which is contained in this file and requires 'iPhone' or 'iPod' to be in the user agent string. I wrote a quick little test app with a web view that just does the following upon viewDidLoad:

[webView loadRequest:
      [NSURLRequest requestWithURL:
        [NSURL URLWithString:
          @"http://itunes.apple.com/nl/app/bluppr-postcards/id348147229?mt=8"]]];

As you say, that opens the App Store app. So I modified it to:

// set some user agent that doesn't have 'iPod' or 'iPhone' in the name
[[NSUserDefaults standardUserDefaults] 
             registerDefaults:[NSDictionary 
                        dictionaryWithObject:@"some old phone or other" 
                        forKey:@"UserAgent"]];

[webView loadRequest:
      [NSURLRequest requestWithURL:
        [NSURL URLWithString:
          @"http://itunes.apple.com/nl/app/bluppr-postcards/id348147229?mt=8"]]];

That displays the page as a web page without opening the app, but there's a problem with the formatting, the displayed page being far too wide. Do a quick search for var deviceDetect= and you'll see that the user agent is also used to determine formatting.

The only solutions I can come up with for that essentially involve screen-scraping-level behaviour. You may subclass NSURLProtocol and add any protocol handler you like via +registerClass:. If you design your protocol to perform HTTP requests then it'll replace the built-in methods for handling HTTP requests. By being selective in which requests you accept or decline, you can do real loading by allowing the HTTP requests you don't want to fall down to the real protocol handler. Hence, you can selectively catch and alter any fetched file before allowing it to be passed to the web view.

You could use that to catch and edit whichever bits of .js and .html you like, but then you're pretty much bound to encounter problems whenever Apple adjust their page.

Similarly, you could use webview's stringByEvaluatingJavaScriptFromString: to execute suitable Javascript to reformat the page after loading, but I'm unable to determine exactly what you'd run and your solution would be just as fragile.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • Thanks! It works great. I didn't knew I was able to change the UserAgent. I use the UIWebView with scalePageToFit and disabled the user interaction. The user only have to see the whole page like an image. So this is a great solution. – Ben Groot Jun 06 '11 at 12:36
  • Changing the user agent by virtue of a user defaults key is something I learnt from StackOverflow, have used myself in shipping apps and have never found fault with, but now that I'm looking I'm honestly unable to tell you where you can find authority for it in the official documentation. So it may actually be worth applying some caution. Sorry for my lack of research in advance, I'm looking into it now... – Tommy Jun 06 '11 at 14:54
  • Sorry but I did copied the code accepted and I get a blanc webview? I have to change any thing there to get it works? help plz..I Get the same issue. – hafedh Dec 22 '11 at 15:14
  • that doesn't work for me. maybe I didn't set a proper user agent. can you please suggest a user agent that prevent launching the iTunes app? thanks – hasan Dec 25 '14 at 01:07