I implement a UIViewController which shows the MapView delegate method in another UIViewController, I'm trying to get the image from Internet when a pin is clicked by user in that MapView by returning the image for that method, but it blocked the main thread so that the whole MapView is blocked by that method. I'm just wondering if there is a way to solve this problem. The following is my method:
Thanks in advance.
Code:
// PhotoMapViewControllerDelegate method to get the clicked thumbnail image
- (UIImage *)photoMapViewController:(PhotoMapViewController *)sender imageForAnnotation:(id<MKAnnotation>)annotation
{
SinglePlacePhotosAnnotations *sppa = (SinglePlacePhotosAnnotations *)annotation;
// check out the folder if the photo already exists
NSFileManager *filemanager = [NSFileManager defaultManager];
NSURL *libraryURL = [[filemanager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *photosURL = [libraryURL URLByAppendingPathComponent:@"Viewd Photos"];
NSString *photoID = [sppa.photo objectForKey:FLICKR_PHOTO_ID];
NSURL *singlePhotoURL = [photosURL URLByAppendingPathComponent:photoID];
dispatch_queue_t getImage = dispatch_queue_create("getImage", NULL);
// local variables in a block is read-only!!!!!!!!!!!
__block UIImage *image = nil;
// use a variable to check if the block is done
__block BOOL blockIsDone = NO;
dispatch_async(getImage, ^ {
if ([filemanager fileExistsAtPath:singlePhotoURL.path]) {
image = [UIImage imageWithContentsOfFile:singlePhotoURL.path];
blockIsDone = YES;
}
else {
NSURL *url = [FlickrFetcher urlForPhoto:sppa.photo format:FlickrPhotoFormatSquare];
NSData *data = [NSData dataWithContentsOfURL:url];
image = [UIImage imageWithData:data];
blockIsDone = YES;
}
});
// block makes it asynchronous like the completion handler, this function returns image before the block
// is done, so have to wait until the block got executed!
while (!blockIsDone) {
usleep(USEC_PER_SEC/10);
}
return image;
}