PHPicker loadObjectOfClass fails with error

We implemented the new PHPicker and have run into an issue we haven't been able to replicate on our own devices but see a lot of users running into it. The problem is an error after getting the PHPickerResults and trying to get the UIImages.

Because the user can select several images at once, what we do is get the results and iterate over each itemProvider object.

I'm following apple's guidance and checking if itemProvider canLoadObjectOfClass:UIImage.class, before executing itemProvider loadObjectOfClass:UIImage.class.
However we are getting hundreds of reports of users where this last method returns an error.

Firstly, this is how we configure our PHPickerViewController:

Code Block
PHPickerConfiguration *configuration = [[PHPickerConfiguration alloc] init];
configuration.selectionLimit = self.pictureSelectionLimit;
configuration.filter = PHPickerFilter.imagesFilter;
configuration.preferredAssetRepresentationMode = PHPickerConfigurationAssetRepresentationModeCurrent;
PHPickerViewController *pickerViewController = [[PHPickerViewController alloc] initWithConfiguration:configuration];
pickerViewController.delegate = self;
pickerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[viewController presentViewController:pickerViewController
              animated:YES
             completion:nil];


And this is what we do with the PHPickerResult. This is a method that returns a block with an array of an object NewPicture instantiated with the UIImage I should be getting.

Code Block
NSMutableArray *picArray = [[NSMutableArray alloc] init];
NSArray *itemProviders = [self.results custom_map: ^id _Nullable (PHPickerResult *_Nonnull current) {
  return current.itemProvider;
}];
dispatch_group_t dispatchGroup = dispatch_group_create();
for (NSItemProvider *itemProvider in itemProviders) {
dispatch_group_enter(dispatchGroup);
/**
 We cannot properly retrieve raw type images with the current authorization status.
 If the image is of type raw, we ignore it.
*/
if ([itemProvider hasItemConformingToTypeIdentifier:@"public.camera-raw-image"]) {
NSException *exception = [NSException exceptionWithName:@"ImageIsTypeRaw"
                        reason:[NSString stringWithFormat:@"Object is type raw. ItemProvider: %@", itemProvider.description]
                       userInfo:nil];
// Log exception...
dispatch_group_leave(dispatchGroup);
continue;
}
if ([itemProvider canLoadObjectOfClass:UIImage.class]) {
[itemProvider loadObjectOfClass:UIImage.class completionHandler: ^(__kindof id <NSItemProviderReading> _Nullable object, NSError *_Nullable error) {
  if ([object isKindOfClass:UIImage.class]) {
NewPicture *picture = [[NewPicture alloc]initWithImage:object];
[picArray addObject:picture];
}
  if (error) {
NSException *exception = [NSException exceptionWithName:@"CouldNotLoadImage"
                        reason:[NSString stringWithFormat:@"Object is nil. UserInfo: %@", error.userInfo]
                       userInfo:error.userInfo];
// Log exception...
}
  dispatch_group_leave(dispatchGroup);
}];
}
}
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^{
picturesBlock(picArray);
});


The most common error we see our users are getting is:

Code Block
Object is nil. UserInfo: {
NSLocalizedDescription = "Cannot load representation of type public.jpeg";
NSUnderlyingError = "Error Domain=NSCocoaErrorDomain Code=260 \"The file \U201cversion=1&uuid=*&mode=current.jpeg\U201d couldn\U2019t be opened because there is no such file.\" UserInfo={NSURL=file:///private/var/mobile/Containers/Shared/AppGroup/*/File%20Provider%20Storage/photospicker/version=1&uuid=*&mode=current.jpeg, NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/*/File Provider Storage/photospicker/version=1&uuid=***&mode=current.jpeg, NSUnderlyingError=0x283822970 {Error Domain=NSPOSIXErrorDomain Code=2 \"No such file or directory\"}}";
}


I'm having a really hard time understanding why this sometimes fails. I'd really appreciate it if someone could give me a hand with this.

I'm attaching the stack trace:






If the asset isn’t available locally, the picker will need to download it first before returning it to the app. It’s possible that some users don’t have a stable internet connection to download the asset. You can show an error alert to explain the situation to your users.
Removed.
Hi! Thanks so much for replying to my question. I did some tests filling up my device disk to have only iCloud photos. In my tests, while it definitely took a bit more time for the picker to return the images, they always downloaded and loaded correctly.

Even simulating a poor internet connection by enabling the network link conditioner, I was unable to reproduce the issue our users are encountering.

Rather more alarming, the instances of these errors are increasing even though we didn’t change any code on our end. And I checked if this was due to more users using the feature, or more users updating to iOS 14, but there doesn’t seem to be any correlation. The one thing I still need to check is if the increase in occurrences are correlated to the the curve of adoption of minor iOS 14 revisions, specifically iOS 14.4, whose time of release seems to match the hike in instances. What i'm trying to pinpoint is if there's a bug on apple's end that causes this unexpected behavior.


Please file a bug report with sysdignose attached so we can further investigate the issue. You can also reply the feedback ID here. Thanks.
If you disconnect your device from the internet and turn on iCloud Photos library, you should be able to repro if selected assets aren’t available locally.

Hi, is there a bug ID? I am seeing the same issue using PHpicker. iPhone 12 iOS 14.8.1

thanks

PHPicker loadObjectOfClass fails with error
 
 
Q