3

I wish to detect when a PDF has been clicked and display it in a separate UIWebView. Here's what I have currently:

- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; {
    NSURL *url = [request URL];
    NSString *urlString = [url absoluteString];
    if (fileType != @"PDF") {

        if([urlString rangeOfString:@".pdf"].location == NSNotFound){
            return true;
        } else {
            NSURL *filePath = [NSURL URLWithString:urlString];
            NSURLRequest *requestObj = [NSURLRequest requestWithURL:filePath];
            [pdfViewer loadRequest:requestObj];
            [self.view addSubview:topView];

            fileType = @"PDF";

            return false;
        }
    } else {
        return true;
    }   
}

This works fine. However it does have one Glaring Flaw:

What about "http://www.example.com/ikb3987basd"

How can I recognise a file type without the extension? Is there some sort of data about the file that I can check on?

Dan Hanly
  • 7,829
  • 13
  • 73
  • 134

3 Answers3

1

You cannot know the content type of a response before you send the request to the server. At this moment, the client has no way of knowing what hides behind a certain URL. Only when the client receives the server's response can it inspect the Content-Type field in the HTTP header.

I believe what you want to achieve is not possible with the public UIWebView API (unless you first start an independent connection to retrieve the header of the URL and check the Content-Type of the response).

Ole Begemann
  • 135,006
  • 31
  • 278
  • 256
  • you emphasised "public UIWebView API" in a way that suggests that you know a way, but not with *that* API? Does this mean you have a solution in mind but would require a download of another component? – Dan Hanly Apr 12 '11 at 12:43
  • No, I don't know a way. But it's clear that `UIWebView` is just a very sparse API over a much more complex framework (WebKit), which is a shame. Apple could clearly expose much more of the workings of `UIWebView` than they do (compare to `WebView` and its numerous delegates on OS X). – Ole Begemann Apr 12 '11 at 13:21
  • I have mentioned the only solution I can think of. Independently retrieve the header of the URL in question. – Ole Begemann Apr 12 '11 at 13:22
  • How do I know the response content-type AFTER I sent the request? – Tom Roggero Jan 04 '16 at 19:41
0

You can use NSURLProtocol sublcass to catch all requests and responses, generated by UIWebView (but not (!) WKWebView).

In AppDelegate in ...didFinishLaunchingWithOptions:

[NSURLProtocol registerClass:[MyCustomProtocol class]];

This will force MyCustomProtocol to handle all network requests.

In implementation of MyCustomProtocol something like (code not tested):

+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
    return YES;
}

+ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request{
    return request;
}

- (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id<NSURLProtocolClient>)client
{
    self = [super initWithRequest:request cachedResponse:cachedResponse client:client];
    if (self) {
         return self;
    }
    return nil;
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    // parse response here for mime-type and content-disposition
    if (shouldDownload) {
        // handle downloading response.URL
        completionHandler(NSURLSessionResponseBecomeDownload);
    } else {
        completionHandler(NSURLSessionResponseAllow);
    }
    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];

}

More details about NSURLProtocol you can find in Apple's example and here

fir
  • 387
  • 1
  • 3
  • 19
0

Using the special theory of relativity you could prove that it is impossible to know about a file when you dont even have it....:p

And furthermore instead of analyzing the whole URL for 'pdf' i would just look at the file extension which you can get from

[[url absoluteString] pathExtension]