Fix permissions regression in RCTCameraRollManager
Summary: In the past (pre D13593314), ALAssetsLibrary camera operations would pop up a permissions dialogue when appropriate and block until the user responded to the dialogue. The calls that we're now using with PHPhotoLibrary immediately return if we don't have permission to access the photo library or haven't asked before, and then asynchronously pop up a permissions dialogue, causing every first photo interaction to fail. Instead we now explicitly check for permissions or request permissions before any operations. Reviewed By: PeteTheHeat Differential Revision: D13620079 fbshipit-source-id: e1befc0ddaec2c1b3334e361f5ae3a3efc5da71d
This commit is contained in:
parent
e172dc7b94
commit
8556340345
|
@ -76,6 +76,26 @@ RCT_EXPORT_MODULE()
|
|||
static NSString *const kErrorUnableToSave = @"E_UNABLE_TO_SAVE";
|
||||
static NSString *const kErrorUnableToLoad = @"E_UNABLE_TO_LOAD";
|
||||
|
||||
static NSString *const kErrorAuthRestricted = @"E_PHOTO_LIBRARY_AUTH_RESTRICTED";
|
||||
static NSString *const kErrorAuthDenied = @"E_PHOTO_LIBRARY_AUTH_DENIED";
|
||||
|
||||
typedef void (^PhotosAuthorizedBlock)(void);
|
||||
|
||||
static void requestPhotoLibraryAccess(RCTPromiseRejectBlock reject, PhotosAuthorizedBlock authorizedBlock) {
|
||||
PHAuthorizationStatus authStatus = [PHPhotoLibrary authorizationStatus];
|
||||
if (authStatus == PHAuthorizationStatusRestricted) {
|
||||
reject(kErrorAuthRestricted, @"Access to photo library is restricted", nil);
|
||||
} else if (authStatus == PHAuthorizationStatusAuthorized) {
|
||||
authorizedBlock();
|
||||
} else if (authStatus == PHAuthorizationStatusNotDetermined) {
|
||||
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
|
||||
requestPhotoLibraryAccess(reject, authorizedBlock);
|
||||
}];
|
||||
} else {
|
||||
reject(kErrorAuthDenied, @"Access to photo library was denied", nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(saveToCameraRoll:(NSURLRequest *)request
|
||||
type:(NSString *)type
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
|
@ -116,11 +136,12 @@ RCT_EXPORT_METHOD(saveToCameraRoll:(NSURLRequest *)request
|
|||
}];
|
||||
};
|
||||
|
||||
void (^loadBlock)(void) = ^void() {
|
||||
if ([type isEqualToString:@"video"]) {
|
||||
inputURI = request.URL;
|
||||
saveBlock();
|
||||
} else {
|
||||
[_bridge.imageLoader loadImageWithURLRequest:request callback:^(NSError *error, UIImage *image) {
|
||||
[self.bridge.imageLoader loadImageWithURLRequest:request callback:^(NSError *error, UIImage *image) {
|
||||
if (error) {
|
||||
reject(kErrorUnableToLoad, nil, error);
|
||||
return;
|
||||
|
@ -130,6 +151,9 @@ RCT_EXPORT_METHOD(saveToCameraRoll:(NSURLRequest *)request
|
|||
saveBlock();
|
||||
}];
|
||||
}
|
||||
};
|
||||
|
||||
requestPhotoLibraryAccess(reject, loadBlock);
|
||||
}
|
||||
|
||||
static void RCTResolvePromise(RCTPromiseResolveBlock resolve,
|
||||
|
@ -191,6 +215,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
|
|||
collectionFetchOptions.predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"localizedTitle == '%@'", groupName]];
|
||||
}
|
||||
|
||||
requestPhotoLibraryAccess(reject, ^{
|
||||
PHFetchResult<PHAssetCollection *> *const assetCollectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:collectionType subtype:collectionSubtype options:collectionFetchOptions];
|
||||
[assetCollectionFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull assetCollection, NSUInteger collectionIdx, BOOL * _Nonnull stopCollections) {
|
||||
// Enumerate assets within the collection
|
||||
|
@ -286,6 +311,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
|
|||
RCTResolvePromise(resolve, assets, hasNextPage);
|
||||
resolvedPromise = YES;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(deletePhotos:(NSArray<NSString *>*)assets
|
||||
|
|
Loading…
Reference in New Issue