Converted RCTImageLoader to be a bridge module

This commit is contained in:
Nick Lockwood 2015-07-27 08:48:31 -07:00
parent d178e27939
commit 2c5290946b
5 changed files with 71 additions and 43 deletions

View File

@ -29,12 +29,12 @@ RCT_EXPORT_METHOD(saveImageWithTag:(NSString *)imageTag
successCallback:(RCTResponseSenderBlock)successCallback
errorCallback:(RCTResponseErrorBlock)errorCallback)
{
[RCTImageLoader loadImageWithTag:imageTag bridge:_bridge callback:^(NSError *loadError, UIImage *loadedImage) {
[_bridge.imageLoader loadImageWithTag:imageTag callback:^(NSError *loadError, UIImage *loadedImage) {
if (loadError) {
errorCallback(loadError);
return;
}
[[RCTImageLoader assetsLibrary] writeImageToSavedPhotosAlbum:[loadedImage CGImage] metadata:nil completionBlock:^(NSURL *assetURL, NSError *saveError) {
[_bridge.assetsLibrary writeImageToSavedPhotosAlbum:[loadedImage CGImage] metadata:nil completionBlock:^(NSURL *assetURL, NSError *saveError) {
if (saveError) {
RCTLogWarn(@"Error saving cropped image: %@", saveError);
errorCallback(saveError);
@ -96,7 +96,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
BOOL __block calledCallback = NO;
NSMutableArray *assets = [[NSMutableArray alloc] init];
[[RCTImageLoader assetsLibrary] enumerateGroupsWithTypes:groupTypes usingBlock:^(ALAssetsGroup *group, BOOL *stopGroups) {
[_bridge.assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:^(ALAssetsGroup *group, BOOL *stopGroups) {
if (group && (groupName == nil || [groupName isEqualToString:[group valueForProperty:ALAssetsGroupPropertyName]])) {
if (assetType == nil || [assetType isEqualToString:@"Photos"]) {

View File

@ -9,37 +9,31 @@
#import <UIKit/UIKit.h>
#import "RCTBridge.h"
@class ALAssetsLibrary;
@class RCTBridge;
typedef void (^RCTImageLoaderProgressBlock)(int64_t written, int64_t total);
typedef void (^RCTImageLoaderCompletionBlock)(NSError *error, id /* UIImage or CAAnimation */);
typedef void (^RCTImageLoaderCompletionBlock)(NSError *error, id image /* UIImage or CAAnimation */);
typedef void (^RCTImageLoaderCancellationBlock)(void);
@interface RCTImageLoader : NSObject
@interface RCTImageLoader : NSObject <RCTBridgeModule>
/**
* The shared asset library instance.
* Loads the specified image at the highest available resolution.
* Can be called from any thread, will always call callback on main thread.
*/
+ (ALAssetsLibrary *)assetsLibrary;
/**
* Can be called from any thread.
* Will always call callback on main thread.
*/
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
bridge:(RCTBridge *)bridge
- (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
callback:(RCTImageLoaderCompletionBlock)callback;
/**
* As above, but includes target size, scale and resizeMode, which are used to
* select the optimal dimensions for the loaded image.
*/
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
- (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
size:(CGSize)size
scale:(CGFloat)scale
resizeMode:(UIViewContentMode)resizeMode
bridge:(RCTBridge *)bridge
progressBlock:(RCTImageLoaderProgressBlock)progress
completionBlock:(RCTImageLoaderCompletionBlock)completion;
@ -54,3 +48,17 @@ typedef void (^RCTImageLoaderCancellationBlock)(void);
+ (BOOL)isRemoteImage:(NSString *)imageTag;
@end
@interface RCTBridge (RCTImageLoader)
/**
* The shared image loader instance
*/
@property (nonatomic, readonly) RCTImageLoader *imageLoader;
/**
* The shared asset library instance.
*/
@property (nonatomic, readonly) ALAssetsLibrary *assetsLibrary;
@end

View File

@ -48,26 +48,21 @@ static dispatch_queue_t RCTImageLoaderQueue(void)
}
@implementation RCTImageLoader
+ (ALAssetsLibrary *)assetsLibrary
{
static ALAssetsLibrary *assetsLibrary = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
assetsLibrary = [[ALAssetsLibrary alloc] init];
});
return assetsLibrary;
ALAssetsLibrary *_assetsLibrary;
}
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
bridge:(RCTBridge *)bridge
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
- (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
callback:(RCTImageLoaderCompletionBlock)callback
{
return [self loadImageWithTag:imageTag
size:CGSizeZero
scale:0
resizeMode:UIViewContentModeScaleToFill
bridge:bridge
progressBlock:nil
completionBlock:callback];
}
@ -116,11 +111,18 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
return nil;
}
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
- (ALAssetsLibrary *)assetsLibrary
{
if (!_assetsLibrary) {
_assetsLibrary = [[ALAssetsLibrary alloc] init];
}
return _assetsLibrary;
}
- (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
size:(CGSize)size
scale:(CGFloat)scale
resizeMode:(UIViewContentMode)resizeMode
bridge:(RCTBridge *)bridge
progressBlock:(RCTImageLoaderProgressBlock)progress
completionBlock:(RCTImageLoaderCompletionBlock)completion
{
@ -229,7 +231,7 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
}];
}
} else if ([imageTag hasPrefix:@"rct-image-store://"]) {
[bridge.imageStoreManager getImageForTag:imageTag withBlock:^(UIImage *image) {
[_bridge.imageStoreManager getImageForTag:imageTag withBlock:^(UIImage *image) {
if (image) {
RCTDispatchCallbackOnMainQueue(completion, nil, image);
} else {
@ -273,3 +275,17 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
}
@end
@implementation RCTBridge (RCTImageLoader)
- (RCTImageLoader *)imageLoader
{
return self.modules[RCTBridgeModuleNameForClass([RCTImageLoader class])];
}
- (ALAssetsLibrary *)assetsLibrary
{
return [self.imageLoader assetsLibrary];
}
@end

View File

@ -15,9 +15,6 @@
#import "RCTUtils.h"
@implementation RCTImageRequestHandler
{
NSInteger _currentToken;
}
RCT_EXPORT_MODULE()
@ -31,9 +28,10 @@ RCT_EXPORT_MODULE()
- (id)sendRequest:(NSURLRequest *)request
withDelegate:(id<RCTURLRequestDelegate>)delegate
{
NSNumber *requestToken = @(++_currentToken);
NSString *URLString = [request.URL absoluteString];
[RCTImageLoader loadImageWithTag:URLString bridge:_bridge callback:^(NSError *error, UIImage *image) {
__block RCTImageLoaderCancellationBlock requestToken = nil;
requestToken = [_bridge.imageLoader loadImageWithTag:URLString callback:^(NSError *error, UIImage *image) {
if (error) {
[delegate URLRequest:requestToken didCompleteWithError:error];
return;
@ -62,4 +60,11 @@ RCT_EXPORT_MODULE()
return requestToken;
}
- (void)cancelRequest:(id /* RCTImageLoaderCancellationBlock */)requestToken
{
if (requestToken) {
((RCTImageLoaderCancellationBlock)requestToken)();
}
}
@end

View File

@ -120,13 +120,12 @@ RCT_NOT_IMPLEMENTED(-init)
};
}
[RCTImageLoader loadImageWithTag:_src
size:self.bounds.size
scale:RCTScreenScale()
resizeMode:self.contentMode
bridge:_bridge
progressBlock:progressHandler
completionBlock:^(NSError *error, id image) {
[_bridge.imageLoader loadImageWithTag:_src
size:self.bounds.size
scale:RCTScreenScale()
resizeMode:self.contentMode
progressBlock:progressHandler
completionBlock:^(NSError *error, id image) {
if ([image isKindOfClass:[CAAnimation class]]) {
[self.layer addAnimation:image forKey:@"contents"];