Change User Agent in UIWebView

IosIphoneCocoa TouchUiwebview

Ios Problem Overview


I have a business need to be able to customize the UserAgent for an embedded UIWebView. (For instance, I'd like the server to respond differently if, say, a user is using one version of the app versus another.)

Is it possible to customize the UserAgent in the existing UIWebView control the way it is, say, for an embedded IE browser in a Windows app?

Ios Solutions


Solution 1 - Ios

Modern Swift

Here's a suggestion for Swift 3+ projects from StackOverflow users PassKit and Kheldar:

UserDefaults.standard.register(defaults: ["UserAgent" : "Custom Agent"])

Source: https://stackoverflow.com/a/27330998/128579

Earlier Objective-C Answer

With iOS 5 changes, I recommend the following approach, originally from this StackOverflow question: https://stackoverflow.com/questions/8487581/uiwebview-ios5-changing-user-agent as pointed out in an answer below. In comments on that page, it appears to work in 4.3 and earlier also.

> Change the "UserAgent" default value by running this code once when > your app starts: > > NSDictionary *dictionary = @{@"UserAgent": @"Your user agent"}; > [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary]; > [[NSUserDefaults standardUserDefaults] synchronize];

See previous edits on this post if you need methods that work in versions of iOS before 4.3/5.0. Note that because of the extensive edits, the following comments / other answers on this page may not make sense. This is a four year old question, after all. ;-)

Solution 2 - Ios

I had this problem too, and tried all methods. I found that only this method works (iOS 5.x): https://stackoverflow.com/questions/8487581/uiwebview-ios5-changing-user-agent

The principle is to set the user agent permanently in the user settings. This works; Webview sends the given header. Just two lines of code:

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"Mozilla/Whatever version 913.6.beta", @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];

Setting User-Agent, or User_Agent in the mutable request, or overriding the setValue in the NSHttpRequest by swizzling, - I tried all that and controlled the results with wireshark, and none of that seems to work, because Webview still uses the user agent value from the user defaults, no matter what you try to set in the NSHttpRequest.

Solution 3 - Ios

It should work with an NSMutableURLRequest as Kuso has written.

NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"http://www.google.com/"]];
[urlRequest setValue: @"iPhone" forHTTPHeaderField: @"User-Agent"]; // Or any other User-Agent value.

You'll have to use NSURLConnection to get the responseData. Set the responseData to your UIWebView and the webView should render:

[webView loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL];

Solution 4 - Ios

Very simple in Swift. Just place the following into your App Delegate.

UserDefaults.standard.register(defaults: ["UserAgent" : "Custom Agent"])

If you want to append to the existing agent string then:

let userAgent = UIWebView().stringByEvaluatingJavaScript(from: "navigator.userAgent")! + " Custom Agent"
UserDefaults.standard.register(defaults: ["UserAgent" : userAgent])

Note: You may will need to uninstall and reinstall the App to avoid appending to the existing agent string.

Solution 5 - Ios

Taking everything this is how it was solved for me:

- (void)viewDidLoad {
    NSURL *url = [NSURL URLWithString: @"http://www.amazon.com"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setValue:@"Foobar/1.0" forHTTPHeaderField:@"User-Agent"];
    [webView loadRequest:request];
}

Thanks Everyone.

Solution 6 - Ios

Using @"User_Agent" simply causes a custom header to appear in the GET request.

> User_agent: Foobar/1.0\r\n
User-Agent: Mozilla/5.0 (iPhone; U; CPU > iPhone OS 3_1_2 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like > Gecko) Mobile/7D11\r\n

The above is what appears in the dissected HTTP packet, essentially confirming what Sfjava was quoting from that forum. It's interesting to note that "User-Agent" gets turned into "User_agent."

Solution 7 - Ios

Actually adding any header field to the NSURLRequest argument in shouldStartLoadWithRequest seems to work, because the request responds to setValue:ForHTTPHeaderField - but it doesn't actually work - the request is sent out without the header.

So I used this workaround in shouldStartLoadWithRequest which just copies the given request to a new mutable request, and re-loads it. This does in fact modify the header which is sent out.

if ( [request valueForHTTPHeaderField:@"MyUserAgent"] == nil )
{
	NSMutableURLRequest *modRequest = [request mutableCopyWithZone:NULL];
	[modRequest setValue:@"myagent" forHTTPHeaderField:@"MyUserAgent"];
	[webViewArgument loadRequest:modRequest];
	return NO;
}

Unfortunately, this still doesn't allow overriding the user-agent http header, which is apparently overwritten by Apple. I guess for overriding it you would have to manage a NSURLConnection by yourself.

Solution 8 - Ios

By pooling the answer by Louis St-Amour and the NSUserDefaults+UnRegisterDefaults category from this question/answer, you can use the following methods to start and stop user-agent spoofing at any time while your app is running:

#define kUserAgentKey @"UserAgent"

- (void)startSpoofingUserAgent:(NSString *)userAgent {
    [[NSUserDefaults standardUserDefaults] registerDefaults:@{ kUserAgentKey : userAgent }];
}

- (void)stopSpoofingUserAgent {
    [[NSUserDefaults standardUserDefaults] unregisterDefaultForKey:kUserAgentKey];
}

Solution 9 - Ios

This solution seems to have been seen as a pretty clever way to do it

changing-the-headers-for-uiwebkit-http-requests

It uses Method Swizzling and you can learn more about it on the CocoaDev page

Give it a look !

Solution 10 - Ios

I faced the same question. I want to add some info to the user-agent, also need to keep the original user-agent of webview. I solved it by using the code below:

    //get the original user-agent of webview
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero];
NSString *oldAgent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
NSLog(@"old agent :%@", oldAgent);

//add my info to the new agent
NSString *newAgent = [oldAgent stringByAppendingString:@" Jiecao/2.4.7 ch_appstore"];
NSLog(@"new agent :%@", newAgent);

//regist the new agent
NSDictionary *dictionnary = [[NSDictionary alloc] initWithObjectsAndKeys:newAgent, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionnary];

Use it before you instancing webview.

Solution 11 - Ios

Try this in the AppDelegate.m

+ (void)initialize 

{

    // Set user agent (the only problem is that we can’t modify the User-Agent later in the program)

    // iOS 5.1

    NSDictionary *dictionnary = [[NSDictionary alloc] initWithObjectsAndKeys:@”Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3”, @”UserAgent”, nil];

   
    [[NSUserDefaults standardUserDefaults] registerDefaults:dictionnary];

}

Solution 12 - Ios

The only problem I have found was change user agent only

- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSDictionary *dictionary = [NSDictionary 
        dictionaryWithObjectsAndKeys:
        @"Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5", 
        @"UserAgent", nil];
    [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
}

Solution 13 - Ios

Apple will soon stop accepting apps with UIWebView. Find below for how you could change the user agent in WKWebView.

let config = WKWebViewConfiguration()

config.applicationNameForUserAgent = "My iOS app"
        
webView = WKWebView(frame: <the frame you need>, configuration: config)

Solution 14 - Ios

To just add a custom content to the current UserAgent value, do the following:

1 - Get the user agent value from a NEW WEBVIEW

2 - Append the custom content to it

3 - Save the new value in a dictionary with the key UserAgent

4 - Save the dictionary in standardUserDefaults.

See the exemple below:

NSString *userAgentP1 = [[[UIWebView alloc] init] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
NSString *userAgentP2 = @"My_custom_value";
NSString *userAgent = [NSString stringWithFormat:@"%@ %@", userAgentP1, userAgentP2];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:userAgent, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSteve MurchView Question on Stackoverflow
Solution 1 - IosLouis St-AmourView Answer on Stackoverflow
Solution 2 - IoswinitzkiView Answer on Stackoverflow
Solution 3 - IosDshutsiView Answer on Stackoverflow
Solution 4 - IosPassKitView Answer on Stackoverflow
Solution 5 - IosMichael RobinsonView Answer on Stackoverflow
Solution 6 - IosdodeskjeggenView Answer on Stackoverflow
Solution 7 - IosDanraView Answer on Stackoverflow
Solution 8 - IosEthanBView Answer on Stackoverflow
Solution 9 - IosOpen SEOView Answer on Stackoverflow
Solution 10 - IosShannon ChouView Answer on Stackoverflow
Solution 11 - IosAitulView Answer on Stackoverflow
Solution 12 - IosSanjeev sharmaView Answer on Stackoverflow
Solution 13 - IosThE uSeFuLView Answer on Stackoverflow
Solution 14 - IosDougView Answer on Stackoverflow