當我使用從其他Web服務檢索到的URL獲取圖像數據時,我需要更新模型對象,但我總是在更新相應視圖時遇到問題。從本質上講,這裏的問題:dataWithContentsOfURL與downloadTaskWithURL
- 呼叫Web服務的
- 檢索圖片網址 - 第一個調用返回使用圖像URL
- 檢索圖像數據
- 更新模型對象與阻止
- 調用Web服務圖像數據
- 更新視圖對象縮略圖(例如:uicollectionviewcell或uitableviewcell)基於模型對象(此處發生問題)
我以前在AFNetworking和相應的NSURLSession中使用過這種方法。但是,問題在於,在更新模型對象之後,我需要在縮略圖圖像出現之前滾動收藏視圖或表格視圖。否則,在第一次加載時,圖像保持空白。
請參考下面的代碼這種方法的一個例子:
- (void)searchFlickrForTerm:(NSString *) term completionBlock:(FlickrSearchCompletionBlock) completionBlock
{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:config
delegate:self
delegateQueue:nil];
NSString *requestString = [Flickr flickrSearchURLForSearchTerm:term];
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if (error != nil) {
completionBlock(term,nil,error);
}
else{
NSDictionary *searchResultsDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
//This is the segment where we parse the Flickr data
NSString * status = searchResultsDict[@"stat"];
if ([status isEqualToString:@"fail"]) {
NSError * error = [[NSError alloc] initWithDomain:@"FlickrSearch" code:0 userInfo:@{NSLocalizedFailureReasonErrorKey: searchResultsDict[@"message"]}];
completionBlock(term, nil, error);
} else {
NSArray *objPhotos = searchResultsDict[@"photos"][@"photo"];
NSMutableArray *flickrPhotos = [@[] mutableCopy];
for(NSMutableDictionary *objPhoto in objPhotos)
{
//Good Idea to parse in the web service call itself. The structure might be different
//If parse in the model class, can be very complicated if the structure is different
FlickrPhoto *photo = [[FlickrPhoto alloc] init];
photo.farm = [objPhoto[@"farm"] intValue];
photo.server = [objPhoto[@"server"] intValue];
photo.secret = objPhoto[@"secret"];
photo.photoID = [objPhoto[@"id"] longLongValue];
NSString *searchURL = [Flickr flickrPhotoURLForFlickrPhoto:photo size:@"m"];
//Call to retrieve image data
NSURLSessionDownloadTask *getImageTask = [_session downloadTaskWithURL:[NSURL URLWithString:searchURL] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){
UIImage *downloadImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
photo.thumbnail = downloadImage;
}];
[getImageTask resume];
[flickrPhotos addObject:photo];
}
completionBlock(term,flickrPhotos,nil);
}
//End parse of Flickr Data
}
}];
[dataTask resume];
//End
}
在上面的代碼段中,後我有解析FlickrPhoto模型對象,我使用NSURLDownloadTask調用圖像的URL。這是有問題的代碼段。
解決方法A:
NSURLSessionDownloadTask *getImageTask = [_session downloadTaskWithURL:[NSURL URLWithString:searchURL] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){
UIImage *downloadImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:location]];
photo.thumbnail = downloadImage;
}];
[getImageTask resume];
然而,正如前面提到的,我已經更新了photo.thumbnail財產,在我uicollectionview,我把我的ImageView從縮略圖屬性來讀取,甚至後,圖像沒有除非我滾動,否則顯示在我的收藏夾視圖中。
但是,有趣的是,而不是使用NSURLDownloadTask,而是使用dataWithContentsOfURL,圖像顯示沒有我需要滾動集合視圖。
方法B:
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:searchURL]
options:0
error:&error];
UIImage *image = [UIImage imageWithData:imageData];
photo.thumbnail = image;
我不知道爲什麼是這樣的情況。我還通過抓取視圖控制器中的主線程來重新加載集合視圖數據。
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
});
我真的很抱歉爲這篇冗長的文章,但我真的很感激,如果有人可以在這方面給我建議。我已經閱讀了文檔,但我仍然能夠找到這個令人困惑的問題的有意義的答案。