使用AFNetworking在iOS下载文件/图像?

我想我已经想通了,但我不能得到它的工作。 我有一个在数组中的每个URL上调用的方法。 此方法有一个图片的URL,应该下载到应用程序支持文件夹中的特定path中供离线使用。 但也许我误解了AFNetwork库中的方法。 我的方法如下所示:

- (void) downloadImageInBackground:(NSDictionary *)args{ @autoreleasepool { NSString *photourl = [args objectForKey:@"photoUrl"]; NSString *articleID = [args objectForKey:@"articleID"]; NSString *guideName = [args objectForKey:@"guideName"]; NSNumber *totalNumberOfImages = [args objectForKey:@"totalNumberOfImages"]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photourl]]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; operation.inputStream = [NSInputStream inputStreamWithURL:[NSURL URLWithString:photourl]]; [operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{ DLog(@"PROBLEMS_AF"); }]; DLog(@"URL_PHOTOURL: %@", photourl); DLog(@"indexSet: %@", operation.hasAcceptableStatusCode); [operation response]; NSData *data = [args objectForKey:@"data"]; NSString *path; path = [NSMutableString stringWithFormat:@"%@/Library/Application Support/Guides", NSHomeDirectory()]; path = [path stringByAppendingPathComponent:guideName]; NSString *guidePath = path; path = [path stringByAppendingPathComponent:photourl]; if ([[NSFileManager defaultManager] fileExistsAtPath:guidePath]){ [[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil]; } DLog(@"path: %@", path); operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO]; [operation start]; DLog(@"isExecuting: %d",[operation isExecuting]); DLog(@"IS_FINISHED: %d",[operation isFinished]); } } 

PhotoURL是我想要下载的图像的直接链接。

由于这种方法被称为所有的图像,所有的日志被称为几次,似乎是正确的。

这里有一些问题。 所以首先,你为什么使用@autoreleasepool ? 我认为这里没有必要。 另外,你使用ARC? 我考虑这个,我的答案的其余部分。

在AFNetworking中有一个名为AFImageRequestOperation的类,所以这对你来说是个好主意。 首先,导入它

 #import "AFImageRequestOperation.h" 

那么你可以创build一个对象

 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photourl]]; AFImageRequestOperation *operation; operation = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil cacheName:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { NSLog(@"%@", [error localizedDescription]); }]; 

现在,在成功块中,你得到了你需要的UIImage。 那里你需要获取文档目录。 你的代码将无法在iOS设备上工作。

 // Get dir NSString *documentsDirectory = nil; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); documentsDirectory = [paths objectAtIndex:0]; NSString *pathString = [NSString stringWithFormat:@"%@/%@",documentsDirectory, guideName]; 

然后你可以使用NSDatas writeToFile

 // Save Image NSData *imageData = UIImageJPEGRepresentation(image, 90); [imageData writeToFile:pathString atomically:YES]; 

最后,你需要开始操作

 [operation start]; 

全部一起:

 - (void)downloadImageInBackground:(NSDictionary *)args{ NSString *guideName = [args objectForKey:@"guideName"]; NSString *photourl = [args objectForKey:@"photoUrl"]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:photourl]]; AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil cacheName:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { // Get dir NSString *documentsDirectory = nil; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); documentsDirectory = [paths objectAtIndex:0]; NSString *pathString = [NSString stringWithFormat:@"%@/%@",documentsDirectory, guideName]; // Save Image NSData *imageData = UIImageJPEGRepresentation(image, 90); [imageData writeToFile:pathString atomically:YES]; } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { NSLog(@"%@", [error localizedDescription]); }]; [operation start]; } 

这里的问题是,操作不被保留。 它将被立即释放。

让操作成为你的类的一个属性,或者让一个操作队列(也是一个属性)处理你的请求(推荐)。 在后一种情况下,不要调用[operation start] 。 当你使用AFHTTPClient ,操作队列也将被pipe理。

你也应该为请求操作注册一个完成callback( setCompletionBlockWithSuccess:failure: