How to get/set user agent on iOS 4.x? - iphone

I have a webview app tool, which essentially consists of the webview and two buttons on a toolbar. One button to view the source of the page, and another button to view/change the current User Agent.
I have both functions working on iOS 5 (view source, and change User Agent), but I cant seem to grab the User Agent in iOS 4.x.
I'm using the following now:
userAgentViewController.UAText = [self.webView stringByEvaluatingJavaScriptFromString:#"navigator.userAgent"];
This works in iOS5, but in iOS 4.x, it doesnt return anything. Is there a way to achieve the same functionality in iOS 4.x?
Thank you!

to get the useragent, check the HTTP header in the NSURLRequest of your response.
You can retreive this one in the webViewDidFinishLoad delegate method.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSLog(#"%#", [[webView request] valueForHTTPHeaderField: #"User-Agent"]);
}
to set it, you have to custom an NSMutableURLRequest and give it to your webView
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:#"yourwebsite.com"]];
[request setHTTPMethod:#"POST"];
[request setValue:USERAGENT_STRING forHTTPHeaderField: #"User-Agent"];
[webView loadRequest:request];
[request release];
and that's it !

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];
}

Related

How to initial a NSURLRequest with user agent

Usually the http user-agent is like:
Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341
If I
NSMutableURLRequest *newUserAgentRequest = (NSMutableURLRequest*)[NSURLRequest requestWithURL:self.url];
NSString *userAgent = [newUserAgentRequest valueForHTTPHeaderField:#"User-Agent"];
the userAgent is nil or empty means
NSMutableURLRequest *newUserAgentRequest = (NSMutableURLRequest*)[NSURLRequest requestWithURL:self.url];
no user-agent includes, how to initial a request with user agent?
I have only done it like the following. This is for iOS devices:
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc]
initWithURL:[NSURL URLWithString:[yourURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
NSString *userAgent = [NSString stringWithFormat:#"%# %#",[UIDevice currentDevice].systemName,[UIDevice currentDevice].systemVersion];
[urlRequest setValue:userAgent forHTTPHeaderField:#"User-Agent"];
Hope it helps
Setting the User_Agent (with an underscore) field works for some, but not all websites, and isn't usually overridden by the NSURL... classes. The other alternative, besides messing with the dictionary (which I believe is not allowed, but I'll post an example anyhow), is method swizzling.
+ (void)initialize {
// Set user agent (the only problem is that we can't modify the User-Agent later in the program)
NSDictionary *dictionnary = [[NSDictionary alloc] initWithObjectsAndKeys:#"Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341", #"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionnary];
//only under MRC do we release [dictionnary release];
}
This works fine for me:
NSString *userAgent = #"My user agent";
NSURL *url = [NSURL URLWithString:#"http://127.0.0.1:9000"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setValue:userAgent forHTTPHeaderField:#"User-Agent"];
The User-Agent is set later if you do not provide one yourself, so it is nil when you try to read it.
Why not subclass NSMutableURLRequest, and in the constructor of your subclass, simply set the "User-Agent" HTTPHeaderField. This will have a less pain point of you always remembering to set the header whenever creating an instance.

iPhone User-Agent

I'm getching content in a universal iOS app using:
NSString stringWithContentsOfURL: [ NSURL URLWithString: link ]
... does that send iPhone/iPad user's IP and User-Agent to the server from which its fetching content from?
I need it to send at least user-agent so I can detect whether its an iPhone or iPad and optimize the content accordingly.
You can use the code below to make sure that the devices is sending an user agent by manually specifying which one to use.
Modified quote from: https://stackoverflow.com/a/1533032/716216
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
NSString* userAgent = #"Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10";
NSURL* url = [NSURL URLWithString:#"http://www.myWebSite.com/"];
NSMutableURLRequest* request = [[[NSMutableURLRequest alloc] initWithURL:url]
autorelease];
[request setValue:userAgent forHTTPHeaderField:#"User-Agent"];
NSURLResponse* response = nil;
NSError* error = nil;
NSData* data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
}
NOTE: The sample user agent I've listed may be dated, and you MAY need to find a newer one.

change user-agent for good

I have been able to change the user-agent by using
- (BOOL)webView:(UIWebView *)webView2 shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSMutableURLRequest *req = (NSMutableURLRequest *)request;
NSString *versionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey];
NSLog(#"user agent = %#", [req valueForHTTPHeaderField: #"User-Agent"]);
if ([req valueForHTTPHeaderField:#"User-Agent"] != NULL) {
[req setValue:[NSString stringWithFormat:#"%# %#", versionString, [req valueForHTTPHeaderField:#"User-Agent"]] forHTTPHeaderField:#"User-Agent"];
NSLog(#"user agent = %#", [req valueForHTTPHeaderField: #"User-Agent"]);
return YES
}
}
But when I go to this website on the device http://whatsmyuseragent.com/ my user-agent hasn't changed. Is there a way to change the user-agent for good?
After playing around for a really long time, I discovered that you can change the User Agent without rooting. Not sure if this helps you if you are building an app.
You cannot change the user-agent displayed by Safari, only the one used by your own application.
I have noticed that the simulator reports nil when testing at times. I'm not sure if this is intentional or on purpose.
You can change the value of the user agent when doing "manual" NSURLRequests but I don't think you can change them in a UIWebView.
Reason being, the values that are passed into the method you show above are not mutable -- you can't change them and expect that the rest of the application will "take" the modifications. Honestly, I'm surprised that casting a NSURLRequest to its mutable variant and then changing it didn't cause your app to crash.

UIWebView links opening in Safari

I want to open an iTunes link in my webView, but when the webView launches the page, it redirects to the Safari browser. There, the url is getting opened, but I want it to open in my webView.
- (void)viewDidLoad {
NSString *urlAddress = #"http://itunes.apple.com/us/app/foodcheck-traffic-light-nutrition/id386368933?mt=8";
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlAddress];
//URL Requst Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[webView loadRequest:requestObj];
[super viewDidLoad];
}
Please suggest a way to sort out this problem.
You may want to try logging the load requests when you run the app. It may be that apple is automatically changing http:// to itms-apps or http://phobos or something along these lines. If so, then you can block the load when it's call using something like this:
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType;
{
NSURL *loadURL = [[request URL] retain];
NSLog(#"%#",loadURL);
if([[loadURL absoluteString] hasPrefix:#"http://"])
{
[loadURL release];
return TRUE;
}
[loadURL release];
return FALSE;
}
Good luck. I'm curious to know what finally works.
A note from the Apple reference documents- Q: How do I launch the App Store from my iPhone application? Also, how do I link to my application on the store?
Note: If you have iTunes links inside
a UIWebView, you can use this
technique after intercepting the links
with the -[UIWebViewDelegate webView:shouldStartLoadWithRequest:navigationType:]
delegate method.
Not sure if you ever got it working, but this works well for me:
NSString *responseString = [NSString stringWithContentsOfURL:myURL];
[self.webView loadHTMLString:responseString baseURL: nil)];

UIWebView shows error when webpage is loaded, Safari shows perfectly

The problem is that the website doesn't fully load in a UIWebView, but it loads normally in Safari.
This is the error I get when loading the website in a UIWebView:
Warning:
cos_before_render(/home/user/ctown/doc_wbn//../sys/swt/www.westspringsec.moe.edu.sg.mob)
[function.cos-before-render]: failed
to open stream: No such file or
directory in
/home/user/ctown/cti_bin/wbn/cos_init.inc
on line 731
Warning: cos_before_render()
[function.include]: Failed opening
'/home/user/ctown/doc_wbn//../sys/swt/www.westspringsec.moe.edu.sg.mob'
for inclusion
(include_path='.:/home/user/ctown/cti_bin/phplot:/usr/local/lib/php')
in
/home/user/ctown/cti_bin/wbn/cos_init.inc
on line 731
Fatal error: Call to undefined
function: json_encode() in
/home/user/ctown/cti_bin/wbn/cos_init.inc
on line 737
- (void)viewDidLoad {
NSString *urlAddress = #"http://www.westspringsec.moe.edu.sg";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[Webview loadRequest:requestObj];
[super viewDidLoad];
}
I tried the question linked below, however I can't modify the backend of the website!
UIWebView Xhmtl parse error but safari don't
The error is not within your code! The UIWebView, especially from within the simulator uses a user agent something like this:
Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 4_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8C134
When you call the url provided it results in the error you are seeing. It's a server side error.
You can alter your user agent by using this code, put it somewhere in the startup phase of your app so it's only set once:
NSDictionary *dictionnary = [[NSDictionary alloc] initWithObjectsAndKeys:#"Safari/528.16", #"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionnary];
[dictionnary release];
With this I was able to open your page. It looks like the site returns different markup for the iphone, so the result with the code above will show the website, which is a bit large for the small display.
UIWebView and Safari does not have the same user agent.
This answer won't fix your issue (see Nick's answer), but you should put [super viewDidLoad]; before you do anything else. So:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *urlAddress = #"http://www.westspringsec.moe.edu.sg";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[Webview loadRequest:requestObj];
}