ALAssetLibrary errors from App store but not in if deployed from Xcode
-
10-12-2019 - |
Question
My application appears to work fine when deployed to my iPhone via Xcode however now that it is on the app store when I download it, it crashes. It must have worked for Apple as like this it would never have passed review????
I have tried other phones but they crash also. From looking at the crash logs the code below is the area of concern.
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// Do a tasks in the background
library = [[ALAssetsLibrary alloc] init];
NSMutableArray *itemFileName = [[NSMutableArray alloc] init];
for (Item *it in tag.Items) {
[itemFileName addObject:it.name];
}
void (^assetEnumerator)( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *asset, NSUInteger index, BOOL *stop) {
if(asset != NULL && [asset valueForProperty:ALAssetPropertyType] == ALAssetTypePhoto) {
ALAssetRepresentation *rep = [asset defaultRepresentation];
NSString *fileName = [rep filename];
if ([itemFileName containsObject:fileName]) {
AssetView *assetView = [[AssetView alloc] initWithAsset:asset];
assetView.delegate = self;
assetView.fileName = fileName;
//assetView.index = counter;
[self.assetViews addObject:assetView];
//NSLog(@"%i",index);
}
}
};
void (^assetGroupEnumerator)( ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
}
else{
//[self performSelectorOnMainThread:@selector(reloadTableView) withObject:nil waitUntilDone:YES];
// Hide the HUD in the main tread
dispatch_async(dispatch_get_main_queue(), ^{
[self reloadTableView];
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
[self loadImageTags];
if([self.assetViews count] != [tag.Items count]){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Info"
message:@"Some items have been deleted from the device. If none remain for this tag it will be deleted."
delegate:self
cancelButtonTitle:nil
otherButtonTitles: @"OK", nil];
[alert show];
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
hud.labelText = @"Cleaning...";
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[self clearupOrphanedItems];
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
});
});
}
});
}
};
// Group Enumerator Failure Block
void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Album Error: %@ - %@", [error localizedDescription], [error localizedRecoverySuggestion]] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
NSLog(@"A problem occured %@", [error description]);
};
// Enumerate Albums
[library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:assetGroupEnumberatorFailure]; //HERE IS WHERE IT DIES!!!
});
I am not sure if the issue is to due with instantiating the ALAssetLibrary inside the block as either it way to works fine during debugging or even just if deployed to phone via Xcode
Can anyone shed some light on this for me?
Solution
To avoid coredata and threading issues, please make sure: 1) that you create only one alassetslibrary Instance for the complete lifecycle of the application. Therefore its recommended you initialize your assetslibrary Instance either in the appdelegate or using dispatch_once 2) Make sure you create the alassetslibrary Instance on the Main thread.
Cheers,
Hendrik