From 558465927d970de1eff70ef91697602093418cb6 Mon Sep 17 00:00:00 2001 From: Iragne Date: Tue, 26 May 2015 14:21:01 +0200 Subject: [PATCH] FIX CRASH Load Assets from Photo library and a memory warning is send. Add a property in Image to force the display to use the [asset thumbnail] method --- Examples/UIExplorer/CameraRollExample.ios.js | 1 + Libraries/Image/Image.ios.js | 12 +++++++++- Libraries/Image/RCTCameraRollManager.m | 2 +- Libraries/Image/RCTImageLoader.h | 2 +- Libraries/Image/RCTImageLoader.m | 11 ++++++++-- Libraries/Image/RCTStaticImageManager.m | 23 +++++++++++++++++++- 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Examples/UIExplorer/CameraRollExample.ios.js b/Examples/UIExplorer/CameraRollExample.ios.js index 73678407213224..02e66a8692412a 100644 --- a/Examples/UIExplorer/CameraRollExample.ios.js +++ b/Examples/UIExplorer/CameraRollExample.ios.js @@ -70,6 +70,7 @@ var CameraRollExample = React.createClass({ return ( diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index 9b84937af84c7c..7e589081026a18 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -65,6 +65,11 @@ var Image = React.createClass({ source: PropTypes.shape({ uri: PropTypes.string, }), + /** + * Force display of the ALAsset in thumbnail format + * This property reduce the memory size and only work with ALAsset + */ + assetThumbnail: PropTypes.bool, /** * A static image to display while downloading the final image off the * network. @@ -163,7 +168,11 @@ var Image = React.createClass({ tintColor: style.tintColor, }); if (isStored) { - nativeProps.imageTag = source.uri; + if (this.props.assetThumbnail === true){ + nativeProps.assetThumbnail = source.uri; + }else{ + nativeProps.imageTag = source.uri; + } } else { nativeProps.src = source.uri; } @@ -188,6 +197,7 @@ var nativeOnlyProps = { defaultImageSrc: true, imageTag: true, contentMode: true, + assetThumb:true, }; if (__DEV__) { verifyPropTypes(Image, RCTStaticImage.viewConfig, nativeOnlyProps); diff --git a/Libraries/Image/RCTCameraRollManager.m b/Libraries/Image/RCTCameraRollManager.m index 8e6c8a532b87bb..6e9c8c2a248cc5 100644 --- a/Libraries/Image/RCTCameraRollManager.m +++ b/Libraries/Image/RCTCameraRollManager.m @@ -25,7 +25,7 @@ @implementation RCTCameraRollManager successCallback:(RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseSenderBlock)errorCallback) { - [RCTImageLoader loadImageWithTag:imageTag callback:^(NSError *loadError, UIImage *loadedImage) { + [RCTImageLoader loadImageWithTag:imageTag thumb:NO callback:^(NSError *loadError, UIImage *loadedImage) { if (loadError) { errorCallback(@[[loadError localizedDescription]]); return; diff --git a/Libraries/Image/RCTImageLoader.h b/Libraries/Image/RCTImageLoader.h index 186a53cd1046b0..b1857f28ddeece 100644 --- a/Libraries/Image/RCTImageLoader.h +++ b/Libraries/Image/RCTImageLoader.h @@ -21,6 +21,6 @@ * Will always call callback on main thread. */ + (void)loadImageWithTag:(NSString *)tag + thumb:(BOOL)thumb callback:(void (^)(NSError *error, id /* UIImage or CAAnimation */ image))callback; - @end diff --git a/Libraries/Image/RCTImageLoader.m b/Libraries/Image/RCTImageLoader.m index 7525b37d0a3273..d40ecd0b43d3ef 100644 --- a/Libraries/Image/RCTImageLoader.m +++ b/Libraries/Image/RCTImageLoader.m @@ -65,7 +65,7 @@ + (ALAssetsLibrary *)assetsLibrary * Can be called from any thread. * Will always call callback on main thread. */ -+ (void)loadImageWithTag:(NSString *)imageTag callback:(void (^)(NSError *error, id image))callback ++ (void)loadImageWithTag:(NSString *)imageTag thumb:(BOOL)thumb callback:(void (^)(NSError *error, id image))callback { if ([imageTag hasPrefix:@"assets-library"]) { [[RCTImageLoader assetsLibrary] assetForURL:[NSURL URLWithString:imageTag] resultBlock:^(ALAsset *asset) { @@ -77,10 +77,17 @@ + (void)loadImageWithTag:(NSString *)imageTag callback:(void (^)(NSError *error, dispatch_async(RCTImageLoaderQueue(), ^{ // Also make sure the image is released immediately after it's used so it // doesn't spike the memory up during the process. + @autoreleasepool { + UIImage *image = nil; ALAssetRepresentation *representation = [asset defaultRepresentation]; ALAssetOrientation orientation = [representation orientation]; - UIImage *image = [UIImage imageWithCGImage:[representation fullResolutionImage] scale:1.0f orientation:(UIImageOrientation)orientation]; + if (!thumb){ + image = [UIImage imageWithCGImage:[representation fullResolutionImage] scale:1.0f orientation:(UIImageOrientation)orientation]; + }else{ + image = [UIImage imageWithCGImage:[asset thumbnail] scale:1.0f orientation:(UIImageOrientation)orientation]; + } + RCTDispatchCallbackOnMainQueue(callback, nil, image); } }); diff --git a/Libraries/Image/RCTStaticImageManager.m b/Libraries/Image/RCTStaticImageManager.m index ce6aab187aedb2..fce7e1eac65620 100644 --- a/Libraries/Image/RCTStaticImageManager.m +++ b/Libraries/Image/RCTStaticImageManager.m @@ -54,7 +54,7 @@ - (UIView *)view RCT_CUSTOM_VIEW_PROPERTY(imageTag, NSString, RCTStaticImage) { if (json) { - [RCTImageLoader loadImageWithTag:[RCTConvert NSString:json] callback:^(NSError *error, id image) { + [RCTImageLoader loadImageWithTag:[RCTConvert NSString:json] thumb:NO callback:^(NSError *error, id image) { if (error) { RCTLogWarn(@"%@", error.localizedDescription); } @@ -70,5 +70,26 @@ - (UIView *)view view.image = defaultView.image; } } +RCT_CUSTOM_VIEW_PROPERTY(assetThumbnail, NSString, RCTStaticImage) +{ + if (json) { + [RCTImageLoader loadImageWithTag:[RCTConvert NSString:json] thumb:YES callback:^(NSError *error, id image) { + if (error) { + RCTLogWarn(@"%@", error.localizedDescription); + } + if ([image isKindOfClass:[CAAnimation class]]) { + [view.layer addAnimation:image forKey:@"contents"]; + } else { + [view.layer removeAnimationForKey:@"contents"]; + view.image = image; + } + }]; + } else { + [view.layer removeAnimationForKey:@"contents"]; + view.image = defaultView.image; + } +} + + @end