I am writing a multithreaded application which needs to upload photos from the ALAssetsLibrary en masse in the background. So I have an NSOperation subclass which finds the appropriate ALAsset via the asset’s URL and adds the image to an upload queue.
In the upload queue for the current ALAsset, I need to get the metadata from the image, but I’ve encountered a problem: both the -metadata and the -fullResolutionImage methods never return when they are called on the ALAssetRepresentation of the ALAsset. They simply hang there indefinitely. I tried printing the value of each of these methods in LLDB, but it hung the debugger up, and I ended up killing Xcode, signal 9 style. These methods are being called on a background queue.
I am testing these on an iPad 2. This is the method in which the ALAsset is added to the upload queue when it is found in the success block of -assetForURL:resultBlock:failureBlock:
- (void)addMediaToUploadQueue:(ALAsset *)media {
@autoreleasepool {
ALAssetRepresentation *defaultRepresentation = [media defaultRepresentation];
CGImageRef fullResolutionImage = [defaultRepresentation fullResolutionImage];
// Return if the user is trying to upload an image which has already been uploaded
CGFloat scale = [defaultRepresentation scale];
UIImageOrientation orientation = [defaultRepresentation orientation];
UIImage *i = [UIImage imageWithCGImage:fullResolutionImage scale:scale orientation:orientation];
if (![self isImageUnique:i]) return;
NSDictionary *imageDictionary = [self dictionaryForAsset:media withImage:i];
dispatch_async(self.background_queue, ^{
NSManagedObjectContext *ctx = [APPDELEGATE createManagedObjectContextForThread];
[ctx setUndoManager:nil];
[ctx performBlock:^{
ImageEntity *newImage = [NSEntityDescription insertNewObjectForEntityForName:@"ImageEntity"
inManagedObjectContext:ctx];
[newImage updateWithDictionary:imageDictionary
inManagedObjectContext:ctx];
[ctx save:nil];
[APPDELEGATE saveContext];
dispatch_async(dispatch_get_main_queue(), ^{
[self.fetchedResultsController performFetch:nil];
});
if (!currentlyUploading) {
currentlyUploading = YES;
[self uploadImage:newImage];
}
}];
});
}
}
I had a similar problem and I was tearing my hair out trying to figure it out.
Turns out while I had thought I setup a singleton for ALAssetsLibrary, my code was not calling it properly and some ALAssets were returning an empty ‘fullResolutionImage’
In all of my NSLogs I must have missed the most important message from Xcode:
“invalid attempt to access ALAssetPrivate past the lifetime of its owning ALAssetsLibrary”
Follow this link
http://www.daveoncode.com/2011/10/15/solve-xcode-error-invalid-attempt-to-access-alassetprivate-past-the-lifetime-of-its-owning-alassetslibrary/
I hope that helps