2014-04-20 51 views
5

我有以下代码:检查URL是一个图像

NSDataDetector* detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil]; 
NSArray* matches = [detector matchesInString:[[imagesArray valueForKey:@"content"] objectAtIndex:indexPath.row] options:0 range:NSMakeRange(0, [[[imagesArray valueForKey:@"content"] objectAtIndex:indexPath.row] length])]; 

这一结果在日志中:

<NSLinkCheckingResult: 0xa632220>{235, 75}{http://URL/wordpress/wp-content/uploads/2014/04/Digital-Board-2.png} 
<NSLinkCheckingResult: 0xa64eb90>{280, 25}{http://www.w3schools.com/} 

我需要做的是检查链接它们是否包含一个图像。在这种情况下,第一个链接包含一个图像(PNG)。第二个不是。我怎样才能做到这一点?

回答

6

您可以为他们获取NSURL,并将扩展名与图片扩展名列表进行比较。像这样的事情也许:

// A list of extensions to check against 
NSArray *imageExtensions = @[@"png", @"jpg", @"gif"]; //... 

// Iterate & match the URL objects from your checking results 
for (NSTextCheckingResult *result in matches) { 
    NSURL *url = [result URL]; 
    NSString *extension = [url pathExtension]; 
    if ([imageExtensions containsObject:extension]) { 
     NSLog(@"Image URL: %@", url); 
     // Do something with it 
    } 
} 
+0

@Leetmorry thanx的编辑:) – Alladinian

5

在此基础上answer你可以使用HTTP HEAD请求,并检查内容类型。
图像可能的内容类型列表是here

代码示例:

- (void)executeHeadRequest:(NSURL *)url { 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
    [request setURL:url]; 
    [request setHTTPMethod:@"HEAD"]; 
    [NSURLConnection connectionWithRequest:request delegate:self] 
} 

// Delegate methods 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    NSHTTPURLResponse *response = (NSHTTPURLResponse *)response; 
    NSString *contentType = [response.allHeaderFields valueForKey:@"Content-Type"]; 
    // Check content type here 
} 
+0

我不知道为什么你downvoted,真实的回答,谢谢! – XelharK

+0

这是更好的答案。检查扩展并不总是可行,例如,返回图像的cgi可能具有.cgi扩展名,即使它返回的是image/jpeg。 Rags93有一个很好的后续简化。 –

0

的问题,当然,有检查环节不看他们背后的资源是它失败的动态Web服务返回的图像,但没有一个典型的图像扩展在网址上。

您可能采取的另一种方法是尝试加载HTTP头并检查返回的MIME类型。您可以将其作为后台任务来完成;并通过加载标题字段,可以最大限度地减少流量。

以下是您可能想要异步执行的某些操作的同步版本。只是为了验证这个想法:

#import <Foundation/Foundation.h> 

BOOL urlIsImage(NSURL *url) 
{ 
    NSMutableURLRequest *request = [[NSURLRequest requestWithURL:url] mutableCopy]; 
    NSURLResponse *response = nil; 
    NSError *error = nil; 
    [request setValue:@"HEAD" forKey:@"HTTPMethod"]; 
    [NSURLConnection sendSynchronousRequest:request 
          returningResponse:&response 
             error:&error]; 
    NSString *mimeType = [response MIMEType]; 
    NSRange range = [mimeType rangeOfString:@"image"]; 
    return (range.location != NSNotFound); 
} 

int main(int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     NSArray *urlStrings = @[@"http://lorempixel.com/400/200/", 
           @"http://stackoverflow.com"]; 
     for(NSString *urlString in urlStrings) { 
      NSURL *url = [NSURL URLWithString:urlString]; 
      if(urlIsImage(url)) { 
       NSLog(@"%@ loads an image",urlString); 
      } 
      else { 
       NSLog(@"%@ does *not* load an image",urlString); 
      } 
     } 
    } 
    return 0; 
} 
+2

还有一个相反的问题。 Dropbox例如具有以文件扩展名结尾的共享链接,但是显示一个html页面而不是实际的文件。 –

0

到Visputs答案类似,您可以从response.MIMEType获得Mime类型。

下面的代码:

- (void)executeHeadRequest:(NSURL *)url { 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
    [request setURL:url]; 
    [request setHTTPMethod:@"HEAD"]; 
    [NSURLConnection connectionWithRequest:request delegate:self] 
} 

// Delegate methods 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    NSLog(@"MIME: %@", response.MIMEType); 
    // Check content type here 
} 
5

在斯威夫特3,带有扩展名是:

extension String { 

    public func isImage() -> Bool { 
     // Add here your image formats. 
     let imageFormats = ["jpg", "jpeg", "png", "gif"] 

     if let ext = self.getExtension() { 
      return imageFormats.contains(ext)   
     } 

     return false 
    } 

    public func getExtension() -> String? { 
     let ext = (self as NSString).pathExtension 

     if ext.isEmpty { 
      return nil 
     } 

     return ext 
    } 

    public func isURL() -> Bool { 
     return URL(string: self) != nil 
    } 

} 

然后在您viewController(或任何你想要的):

let str = "string" 

// Check if the given string is an URL and an image 
if str.isURL() && str.isImage() { 
    print("image and url") 
} 

注意:此方法适用于指向具有名称和扩展名的图像资源的URL,例如:http://www.yourwebapi.com/api/image.jpg, ,但不适用于以下网址:http://www.yourwebapi.com/api/images/12626,因为在这种情况下,URL字符串不会告诉我们关于mime类型的一切。

如@Visput所示,您应该查看Content-Type HTTP Header并检查返回的MIME类型。例如,image/jpeg

0

由于NSURLConnection已弃用。

类似的代码获得的contentType

- (void)executeHeadRequest:(NSURL *)url { 

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
[request setHTTPMethod:@"HEAD"]; 
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; 
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig]; 

[[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 
    if (!error) { 

     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 
     NSString *contentType = [httpResponse.allHeaderFields valueForKey:@"Content-Type"]; 
     if ([contentType contains:@"image"]) { 

      NSLog(@"Url is image type"); 
     } 
    } 
    [session invalidateAndCancel]; 
}] resume]; 

}

相关问题