2016-03-03 65 views
1

我需要知道文件网页,可在特定URL并根据MIMEType我会做出决定是否要的MIMEType将该页面/文件加载到UIWebView或不。 我知道,我可以得到MIMETypeNSURLResponse对象,但问题是,当我得到这个响应,该页面已经下载。获取MIMETYPE通过请求文件/网页的标题驻留在URL

那么,有没有什么办法可以要求在特定URL文件/网页的只有头,这样我可以检查该网页/文件MIMEType和要求,只有在需要的时候?

回答

1

你只想得到标题。为此,使用HTTP HEAD方法。例如:

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" 
} 
1

您可以通过使用响应头的“内容类型”属性来获取内容类型直到您确定响应的内容类型。为此,你可以实现一个自定义的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 

还有一件事我忘了要提到的是,你必须在你的应用代理中注册CustomURLProtocol,如下所示:

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

我看你不希望在UIWebView中要加载的页面:

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