views:

1183

answers:

2

I have a programatically crated UIWebView, and it is used to browse a iPhone-style site stored on my server. In this website, there are a few links to files users can download into my application. Right now, I'm trying to detect this with:

- (BOOL) webView:(UIWebView *) webView shouldStartLoadWithRequest:(NSURLRequest *) request navigationType:(UIWebViewNavigationType) navigationType
{
    url = [request URL];
    NSString *mimeType = [request valueForHTTPHeaderField:@"Content-Type"];
    NSLog(@"Content-type: %@", mimeType);
    if(mimeType == @"application/zip" || mimeType == @"application/x-zip" || mimeType == @"application/octet-stream")
    {
     NSLog(@"Downloading file!");
     [NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:@"/tmp/file.ipa"];
     return NO;
    }
    return YES;
}

However, when this method is called, the content-type header is almost always (null), so I never am able to download a file.

How would you do this correctly?

+1  A: 

You're trying to detect a Content-Type from an NSURLRequest which has not yet been made. You won't know the Content-Type until after the request is made using NSURLConnection. In this case, I'd probably just look at the file extension of the URL path.

Ben Gottlieb
The issue with that is the URLs are stored in a system that does not have filenames, it shows up more as http://example.com/some/stuff/32f3121a234ae32423
chpwn
I believe if you use an httpMethod of "HEAD", then you'll just get headers. However, this will require a content call after the initial tap.
Ben Gottlieb
A: 

So here's the problem: UIWebView doesn't download anything it can't display, and it doesn't know how to display a ZIP file. It will always fail before the Content-Type is filled in.

So, what to do? I don't know if your server-side app runs on more than the iPhone, but you could register a custom URL scheme with links like myapplication://example.com/stuff/yourhexurlgoeshere. You can create a custom URL handler for the myapplication scheme. A couple of seconds of Googling produced this site, which explains how to do it.

This has an additional benefit because if you, say, emailed such a link to another user, they could tap on it in Mail and have it open in your application.

Alex
Is there a method to just get the returned headers, via something like a NSURLConnection? Then I could manually scan for the zip file myself, but I would prefer if I did not have to download the entire page twice, just to check the headers.
chpwn
Not really, `webView:shouldStartLoadWithRequest:` is expecting you to return a value. You'd have to freeze your whole application for potentially several seconds to do a synchronous `NSURLRequest` to get the headers. It's a surprisingly tough problem.
Alex
However, I could just return YES no matter what after firing off an asyncronous one, and then have it start the download potentially a few seconds late (which is perfectly fine).But, how would I just get the headers?
chpwn
This is true. If you kick off an `NSURLConnection`, the delegate method `connection:didReceiveResponse:` gives you an `NSURLResponse`, which will have the MIME type. Kaboom.
Alex