mirror of
https://github.com/status-im/react-native.git
synced 2025-01-15 20:15:11 +00:00
1d6d1189f0
Summary: public The image loader was previously returning on the main thread, which could lead to poor performance due to various call sites doing further image processing (resizing, cropping, etc.) directly in the completion block. This diff modifies the loader to return on a background thread (the same one used to load the image), and updates the call sites to dispatch to the explicit thread they need. Reviewed By: javache Differential Revision: D2549774 fb-gh-sync-id: fed73b7c163fdf67ff65bae72ab1986327e75815
98 lines
3.5 KiB
Objective-C
98 lines
3.5 KiB
Objective-C
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
#import "RCTPhotoLibraryImageLoader.h"
|
|
|
|
#import <Photos/Photos.h>
|
|
|
|
#import "RCTImageUtils.h"
|
|
#import "RCTUtils.h"
|
|
|
|
@implementation RCTPhotoLibraryImageLoader
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
@synthesize bridge = _bridge;
|
|
|
|
#pragma mark - RCTImageLoader
|
|
|
|
- (BOOL)canLoadImageURL:(NSURL *)requestURL
|
|
{
|
|
return [requestURL.scheme caseInsensitiveCompare:@"ph"] == NSOrderedSame;
|
|
}
|
|
|
|
- (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
resizeMode:(UIViewContentMode)resizeMode
|
|
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
|
|
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
|
|
{
|
|
// Using PhotoKit for iOS 8+
|
|
// The 'ph://' prefix is used by FBMediaKit to differentiate between
|
|
// assets-library. It is prepended to the local ID so that it is in the
|
|
// form of an, NSURL which is what assets-library uses.
|
|
NSString *phAssetID = [imageURL.absoluteString substringFromIndex:@"ph://".length];
|
|
PHFetchResult *results = [PHAsset fetchAssetsWithLocalIdentifiers:@[phAssetID] options:nil];
|
|
if (results.count == 0) {
|
|
NSString *errorText = [NSString stringWithFormat:@"Failed to fetch PHAsset with local identifier %@ with no error message.", phAssetID];
|
|
completionHandler(RCTErrorWithMessage(errorText), nil);
|
|
return ^{};
|
|
}
|
|
|
|
PHAsset *asset = [results firstObject];
|
|
PHImageRequestOptions *imageOptions = [PHImageRequestOptions new];
|
|
|
|
if (progressHandler) {
|
|
imageOptions.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
|
|
static const double multiplier = 1e6;
|
|
progressHandler(progress * multiplier, multiplier);
|
|
};
|
|
}
|
|
|
|
// Note: PhotoKit defaults to a deliveryMode of PHImageRequestOptionsDeliveryModeOpportunistic
|
|
// which means it may call back multiple times - we probably don't want that
|
|
|
|
BOOL useMaximumSize = CGSizeEqualToSize(size, CGSizeZero);
|
|
CGSize targetSize;
|
|
if (useMaximumSize) {
|
|
targetSize = PHImageManagerMaximumSize;
|
|
imageOptions.resizeMode = PHImageRequestOptionsResizeModeNone;
|
|
imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
|
|
} else {
|
|
targetSize = size;
|
|
imageOptions.resizeMode = PHImageRequestOptionsResizeModeFast;
|
|
imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
|
|
}
|
|
|
|
PHImageContentMode contentMode = PHImageContentModeAspectFill;
|
|
if (resizeMode == UIViewContentModeScaleAspectFit) {
|
|
contentMode = PHImageContentModeAspectFit;
|
|
}
|
|
|
|
PHImageRequestID requestID =
|
|
[[PHImageManager defaultManager] requestImageForAsset:asset
|
|
targetSize:targetSize
|
|
contentMode:contentMode
|
|
options:imageOptions
|
|
resultHandler:^(UIImage *result, NSDictionary *info) {
|
|
if (result) {
|
|
completionHandler(nil, result);
|
|
} else {
|
|
completionHandler(info[PHImageErrorKey], nil);
|
|
}
|
|
}];
|
|
|
|
return ^{
|
|
[[PHImageManager defaultManager] cancelImageRequest:requestID];
|
|
};
|
|
}
|
|
|
|
@end
|