通过请求文件/网页的标题驻留在URL获取MIMETYPE

时间:2016-03-03 09:11:14

标签: ios swift uiwebview

我需要知道文件MIMEType网页,特定URL并根据MIMEType提供我将决定是否将该页面/文件加载到UIWebView。 我知道,我可以使用MIMEType对象获取NSURLResponse,但问题是,当我收到此回复时,该页面已经下载。

那么,有没有办法只询问特定URL文件/网页的标题,以便我可以检查MIMEType并请求该页面/文件,只有在需要时?

3 个答案:

答案 0 :(得分:2)

在您确定响应的Content-Type之前,我发现您不希望在UIWebView中加载页面。为此,您可以实现自定义NSURLProtocol。这就是我所做的,但我们随时欢迎您加强或提出不同的解决方案。请仔细阅读内联评论。

***** CustomURLProtocol.h *****

@interface CustomURLProtocol : NSURLProtocol

@end

***** CustomURLProtocol.m *****

@interface CustomURLProtocol ()

@property(nonatomic, strong) NSURLConnection * connection;
@property(nonatomic, strong) NSMutableData * reponseData;
@property(nonatomic, strong) NSURLRequest * originalRequest;

@end

@implementation CustomURLProtocol

+(BOOL)canInitWithRequest:(NSURLRequest *)request
{

    NSString * urlScheme = [request.URL.scheme lowercaseString];

    //only handling HTTP or HTTPS requests which are not being handled
    return (![[NSURLProtocol propertyForKey:@"isBeingHandled" inRequest:request] boolValue] &&
            ([urlScheme isEqualToString:@"http"] || [urlScheme isEqualToString:@"https"]));
}

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


-(void)startLoading
{
    NSMutableURLRequest * requestCopy = [self.request mutableCopy];
    [NSURLProtocol setProperty:[NSNumber numberWithBool:YES] forKey:@"isBeingHandled" inRequest:requestCopy];
    self.originalRequest = requestCopy;
    self.connection = [NSURLConnection connectionWithRequest:requestCopy delegate:self];
}

-(void)stopLoading
{
    [self.connection cancel];
}

#pragma mark - NSURLConnectionDelegate methods


-(NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
{

    [self.client URLProtocol:self wasRedirectedToRequest:request redirectResponse:response];

    return request;
}



- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    if ([response isKindOfClass:[NSHTTPURLResponse class]])
    {
        NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;
        NSString * contentType = [httpResponse.allHeaderFields valueForKey:@"Content-Type"];

        /*
         Check any header here and make the descision.
         */
        if([contentType containsString:@"application/pdf"])
        {

            /*
                Let's say you don't want to load the PDF in current UIWebView instead you want to open another view controller having a webview for that.
                For doing that we will not inform the client about the response we received from NSURLConnection that we created.
             */

            [self.connection cancel];

            //post a notification carrying the PDF request and load this request anywhere else.
            [[NSNotificationCenter defaultCenter] postNotificationName:@"PDFRequest" object:self.originalRequest];
        }
        else
        {
            /*
                For any other request having Content-Type other than application/pdf,
                we are informing the client (UIWebView or NSURLConnection) and allowing it to proceed.
             */
            [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
        }
    }

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.client URLProtocol:self didLoadData:data];
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

    [self.client URLProtocolDidFinishLoading:self];
}

- (void)connection:(NSURLConnection *)connectionLocal didFailWithError:(NSError *)error
{
    [self.client URLProtocol:self didFailWithError:error];
}

@end

我忘了提到的另一件事是你必须在你的app delegate中注册CustomURLProtocol,如下所示:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   [NSURLProtocol registerClass:[CustomURLProtocol class]];
    return YES;
}

答案 1 :(得分:1)

您只想获取标题。使用 HTTP HEAD 方法。例如:

    let request = NSMutableURLRequest(URL: NSURL(string: "your_url")!)
    request.HTTPMethod = "HEAD"
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
        // Analyze response here
    }
    task.resume()

答案 2 :(得分:1)

您可以使用响应标头的“Content-Type”属性来获取内容类型:

func getContentType(urlPath: String, completion: (type: String)->()) {
    if let url = NSURL(string: urlPath) {
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "HEAD"
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (_, response, error) in
            if let httpResponse = response as? NSHTTPURLResponse where error == nil {
                if let ct = httpResponse.allHeaderFields["Content-Type"] as? String {
                    completion(type: ct)
                }
            }
        }
        task.resume()
    }
}

getContentType("http://example.com/pic.jpg") { (type) in
    print(type)  // prints "image/jpeg"
}