Update image loader plugins

This commit is contained in:
Alex Akers 2015-09-03 05:53:16 -07:00
parent aa62a5e4e0
commit 8187d1f0ec
6 changed files with 52 additions and 52 deletions

View File

@ -50,14 +50,13 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2)
RCTImageLoader *imageLoader = [RCTImageLoader new];
NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil moduleProvider:^{ return @[loader, imageLoader]; } launchOptions:nil];
RCTImageLoaderCancellationBlock cancelBlock = [imageLoader loadImageWithTag:@"http://facebook.github.io/react/img/logo_og.png" size:CGSizeMake(100, 100) scale:1.0 resizeMode:UIViewContentModeScaleAspectFit progressBlock:^(int64_t progress, int64_t total) {
[imageLoader loadImageWithTag:@"http://facebook.github.io/react/img/logo_og.png" size:CGSizeMake(100, 100) scale:1.0 resizeMode:UIViewContentModeScaleAspectFit progressBlock:^(int64_t progress, int64_t total) {
XCTAssertEqual(progress, 1);
XCTAssertEqual(total, 1);
} completionBlock:^(NSError *loadError, id loadedImage) {
XCTAssertEqualObjects(loadedImage, image);
XCTAssertNil(loadError);
}];
XCTAssertNil(cancelBlock);
}
- (void)testImageLoaderUsesImageURLLoaderWithHighestPriority
@ -82,14 +81,13 @@ RCTDefineImageDecoder(RCTImageLoaderTestsDecoder2)
RCTImageLoader *imageLoader = [RCTImageLoader new];
NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil moduleProvider:^{ return @[loader1, loader2, imageLoader]; } launchOptions:nil];
RCTImageLoaderCancellationBlock cancelBlock = [imageLoader loadImageWithTag:@"http://facebook.github.io/react/img/logo_og.png" size:CGSizeMake(100, 100) scale:1.0 resizeMode:UIViewContentModeScaleAspectFit progressBlock:^(int64_t progress, int64_t total) {
[imageLoader loadImageWithTag:@"http://facebook.github.io/react/img/logo_og.png" size:CGSizeMake(100, 100) scale:1.0 resizeMode:UIViewContentModeScaleAspectFit progressBlock:^(int64_t progress, int64_t total) {
XCTAssertEqual(progress, 1);
XCTAssertEqual(total, 1);
} completionBlock:^(NSError *loadError, id loadedImage) {
XCTAssertEqualObjects(loadedImage, image);
XCTAssertNil(loadError);
}];
XCTAssertNil(cancelBlock);
}
- (void)testImageDecoding

View File

@ -24,7 +24,7 @@ RCT_EXPORT_MODULE()
char header[7] = {};
[imageData getBytes:header length:6];
return !strcmp(header, "GIF87a") == 0 || !strcmp(header, "GIF89a");
return !strcmp(header, "GIF87a") || !strcmp(header, "GIF89a");
}
- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)imageData size:(CGSize)size scale:(CGFloat)scale resizeMode:(UIViewContentMode)resizeMode completionHandler:(RCTImageLoaderCompletionBlock)completionHandler

View File

@ -37,8 +37,10 @@ RCT_EXPORT_MODULE()
- (BOOL)canLoadImageURL:(NSURL *)requestURL
{
// Have to exclude 'file://' from the main bundle, otherwise this would conflict with RCTAssetBundleImageLoader
return [requestURL.scheme.lowercaseString hasPrefix:@"http"] ||
([requestURL.scheme.lowercaseString hasPrefix:@"file"] && ![requestURL.path hasPrefix:[NSBundle mainBundle].resourcePath]);
return
[requestURL.scheme compare:@"http" options:NSCaseInsensitiveSearch range:NSMakeRange(0, 4)] == NSOrderedSame ||
([requestURL.scheme caseInsensitiveCompare:@"file"] == NSOrderedSame && ![requestURL.path hasPrefix:[NSBundle mainBundle].resourcePath]) ||
[requestURL.scheme caseInsensitiveCompare:@"data"] == NSOrderedSame;
}
/**
@ -103,7 +105,7 @@ RCT_EXPORT_MODULE()
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
if ([imageURL.scheme isEqualToString:@"http"]) {
if ([imageURL.scheme.lowercaseString hasPrefix:@"http"]) {
__block RCTImageLoaderCancellationBlock decodeCancel = nil;
__weak RCTImageDownloader *weakSelf = self;
@ -122,9 +124,37 @@ RCT_EXPORT_MODULE()
decodeCancel();
}
};
} else if ([imageURL.scheme caseInsensitiveCompare:@"data"] == NSOrderedSame) {
__block BOOL cancelled = NO;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (cancelled) {
return;
}
// Normally -dataWithContentsOfURL: would be bad but this is a data URL.
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:data];
if (image) {
if (progressHandler) {
progressHandler(1, 1);
}
if (completionHandler) {
completionHandler(nil, image);
}
} else {
if (completionHandler) {
NSString *message = [NSString stringWithFormat:@"Invalid image data for URL: %@", imageURL];
completionHandler(RCTErrorWithMessage(message), nil);
}
}
});
return ^{
cancelled = YES;
};
} else if ([imageURL.scheme isEqualToString:@"file"]) {
__block BOOL cancelled = NO;
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (cancelled) {
return;
}

View File

@ -87,9 +87,21 @@ RCT_EXPORT_MODULE()
RCTLogError(@"No suitable image URL loader found for %@", imageTag);
}
return [loadHandler loadImageForURL:requestURL size:size scale:scale resizeMode:resizeMode progressHandler:progressBlock completionHandler:^(NSError *error, id image) {
return [loadHandler loadImageForURL:requestURL size:size scale:scale resizeMode:resizeMode progressHandler:^(int64_t progress, int64_t total) {
if (!progressBlock) {
return;
}
if ([NSThread isMainThread]) {
progressBlock(progress, total);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
progressBlock(progress, total);
});
}
} completionHandler:^(NSError *error, id image) {
RCTDispatchCallbackOnMainQueue(completionBlock, error, image);
}];
}] ?: ^{};
}
- (id<RCTImageDecoder>)imageDecoderForRequest:(NSData *)imageData

View File

@ -6,7 +6,7 @@
#import "RCTImageLoader.h"
#import "RCTURLRequestHandler.h"
@interface RCTImageStoreManager : NSObject <RCTImageURLLoader, RCTURLRequestHandler>
@interface RCTImageStoreManager : NSObject <RCTImageURLLoader>
/**
* Set and get cached images. These must be called from the main thread.

View File

@ -97,46 +97,6 @@ RCT_EXPORT_METHOD(addImageFromBase64:(NSString *)base64String
}
}
#pragma mark - RCTURLRequestHandler
- (BOOL)canHandleRequest:(NSURLRequest *)request
{
return [request.URL.scheme.lowercaseString isEqualToString:@"rct-image-store"];
}
- (id)sendRequest:(NSURLRequest *)request
withDelegate:(id<RCTURLRequestDelegate>)delegate
{
NSString *imageTag = request.URL.absoluteString;
[self getImageForTag:imageTag withBlock:^(UIImage *image) {
if (!image) {
NSError *error = RCTErrorWithMessage([NSString stringWithFormat:@"Invalid imageTag: %@", imageTag]);
[delegate URLRequest:request didCompleteWithError:error];
return;
}
NSString *mimeType = nil;
NSData *imageData = nil;
if (RCTImageHasAlpha(image.CGImage)) {
mimeType = @"image/png";
imageData = UIImagePNGRepresentation(image);
} else {
mimeType = @"image/jpeg";
imageData = UIImageJPEGRepresentation(image, 1.0);
}
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL
MIMEType:mimeType
expectedContentLength:imageData.length
textEncodingName:nil];
[delegate URLRequest:request didReceiveResponse:response];
[delegate URLRequest:request didReceiveData:imageData];
[delegate URLRequest:request didCompleteWithError:nil];
}];
return request;
}
#pragma mark - RCTImageLoader
- (BOOL)canLoadImageURL:(NSURL *)requestURL