在我的iphone应用程序中,我正在从网上下载一些图像。如果它阻止UI线程并不重要,事实上它需要阻止UI线程直到完全下载。完成后,我会通知用户界面唤醒并显示它们。
我的(简化)代码如下:
for (int i=0; i<10; i++)
{
//call saveImageFromURL (params)
}
//Call to Notify UI to wake up and show the images
+(void) saveImageFromURL:(NSString *)fileURL :(NSString *)destPath :(NSString *)fileName
{
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
NSFileManager * fileManager = [NSFileManager defaultManager];
BOOL bExists, isDir;
bExists = [fileManager fileExistsAtPath:destPath isDirectory:&isDir];
if (!bExists)
{
NSError *error = nil;
[fileManager createDirectoryAtPath:destPath withIntermediateDirectories:YES attributes:nil error:&error];
if (error)
{
NSLog(@"%@",[error description]);
return;
}
}
NSString *filePath = [destPath stringByAppendingPathComponent:fileName];
[data writeToFile:filePath options:NSAtomicWrite error:nil];
}
当我完成for
循环后,我非常确定所有图像都存储在本地。它在模拟器中工作正常。
然而,它在我的设备上无效。 UI在存储图像之前唤醒。几乎所有图像都显得空洞。
我做错了什么?
答案 0 :(得分:1)
dataWithContentsOfURL:
将返回nil或者它不是正确的图像数据,例如404找不到[data writeToFile:filePath]
的错误,以查看保存的详细信息。答案 1 :(得分:0)
经过一些研究,我使用AFHttpClient enqueueBatchOfHTTPRequestOperations
来完成多个文件下载。
这是怎么回事:
//Consider I get destFilesArray filled with Dicts already with URLs and local paths
NSMutableArray * opArray = [NSMutableArray array];
AFHTTPClient *httpClient = nil;
for (id item in destFilesArray)
{
NSDictionary * fileDetailDict = (NSDictionary *)item;
NSString * url = [fileDetailDict objectForKey:@"fileURL"];
if (!httpClient)
httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:url]];
NSString * filePath = [photoDetailDict objectForKey:@"filePath"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];
[opArray addObject:operation];
}
[httpClient enqueueBatchOfHTTPRequestOperations:opArray progressBlock:nil completionBlock:^(NSArray *operations)
{
//gets called JUST ONCE when all operations complete with success or failure
for (AFJSONRequestOperation *operation in operations)
{
if (operation.response.statusCode != 200)
{
NSLog(@"operation: %@", operation.request.URL);
}
}
}];