Code, Code, Revolution!
In each new version of iOS the browser gets a new user-agent string. I’ve been searching for a way to get the user-agent string from the API but haven’t been able to find a straight forward way to do it. Here’s my solution:
BSWebViewUserAgent.h
#import <Foundation/Foundation.h>
@interface BSWebViewUserAgent : NSObject <UIWebViewDelegate> {
NSString *userAgent;
UIWebView *webView;
}
@property (nonatomic, retain) NSString *userAgent;
-(NSString*)userAgentString;
@endBSWebViewUserAgent.m
#import "BSWebViewUserAgent.h"
@implementation BSWebViewUserAgent
@synthesize userAgent;
-(NSString*)userAgentString
{
webView = [[UIWebView alloc] init];
webView.delegate = self;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"www.google.com"]]];
// Wait for the web view to load our bogus request and give us the secret user agent.
while (self.userAgent == nil)
{
// This executes another run loop.
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
return self.userAgent;
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
self.userAgent = [request valueForHTTPHeaderField:@"User-Agent"];
// Return no, we don't care about executing an actual request.
return NO;
}
- (void)dealloc
{
[webView release];
[userAgent release];
[super dealloc];
}
@endI use a UIWebView, listen to its delegates and load a bogus URL. When shouldStartLoadWithRequest is called the supplied request contains the user-agent string in the header. Because UIWebView loadRequest is asynchronous and we’re not really loading a request because we return NO in shouldStartLoadWithRequest there’s a loop waiting for the user-agent to be set. To wait for an asynchronous task to complete NSRunLoop is used. Each call to NSRunLoop runMode makes the application execute another loop, in this case executing the loadRequest call for our UIWebView.
Using the class is simple:
BSWebViewUserAgent *agent = [[BSWebViewUserAgent alloc] init]; NSLog(@"User-agent: %@", [agent userAgentString]); [agent release];
This executes very fast, but if you have found an easier/faster way of extracting the user-agent, please let me know.
With this blog I try to provide useful tips and solutions for programming .NET, Objective-C and more. My name is Björn Sållarp, and I love writing code.
iPhone/iPad – Wait for asynchronous tasks to complete | blog.sallarp.com
July 27th, 2010 at 11:36 am
[...] a rare case but sometimes you need to do this. I used this techinque in my previous post on how to extract the user-agent string from a UIWebView. Check it out for a more complete [...]