Dan Hanly
Dan Hanly

Reputation: 7839

Recognising UIWebView file types

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?

Upvotes: 3

Views: 2460

Answers (3)

fir
fir

Reputation: 387

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

Upvotes: 0

user283455
user283455

Reputation:

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]

Upvotes: 0

Ole Begemann
Ole Begemann

Reputation: 135550

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).

Upvotes: 1

Related Questions