iosobjective-cuiwebviewuser-agentnsurlrequest

Set different User-Agents for multiple UIWebViews


My app has UIWebViews, some loading sites where I need the desktop version of the site, some loading sites where I need the mobile version of the site.

So I set the user-agent to a desktop user-agent or a mobile user-agent to achieve this.

For example if I want a UIWebView to load a site's Desktop version I will simply run this code right before:

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36", @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];

The problem is that this of course is setting a NSUserDefaults variable, meaning for any UIWebView in my app that loads after this it will use the desktop user agent. I can just flip flop the NSUserAgent as needed between desktop and mobile and load accordingly but sometimes my app requires TWO UIWebViews to load at the same time, one mobile, one desktop.

Is there any way I can set the user-agent of a UIWebView specific to said UIWebView?

I'm assuming this is going to involve swizzling NSUrlRequest methods or something? I know very little about that stuff


Solution

  • The easy way, if possible, is to just use WKWebView instead of UIWebView. WKWebView exposes the user agent string as a property on the class itself (.customUserAgent, iOS9+). As an added bonus, JavaScript code running in the view will be faster and will use less battery power because the JavaScript can be precompiled into native code.

    That said, if you have to stick with UIWebView for some reason, you could create an NSURLProtocol that intercepts all your app's HTTP requests and changes the field depending on the hostname in the URL. There are some examples of an NSURLProtocol on Apple's website. Start with that and tweak as needed.