[ReactNative] Refactor RCTDataManager to support pluggable data source modules (RCTURLRequestHandlers)

Summary:
@public

This is a refactor of @philikon's original diff that decouples the dependencies between the Network and Image modules, and replaces RCTDataQueryExecutor with a more useful abstraction.

I've introduced the RCTURLRequestHandler protocol, which is a new type of bridge module used for loading data using an NSURLRequest. RCTURLRequestHandlers can be registered using RCT_EXPORT_MODULE() and are then available at runtime for use by the RCTDataManager, which will automatically select the appropriate handler for a given request based on the handler's self-reported capabilities.

The currently implemented handlers are:

- RCTHTTPRequestHandler - the standard open source HTTP request handler that uses NSURLSession
- RKHTTPRequestHandler - the internal FB HTTP request handler that uses FBNetworking
- RCTImageRequestHandler - a handler for loading local images from the iOS asset-library

Depends on D2108193

Test Plan:
- Internal apps still work
- OSS port still compiles, Movies app and a sample Parse app still work
- uploading image to Parse using the above code snippet works
- tested `FormData` with string and image parameters using http://www.posttestserver.com/
This commit is contained in:
Nick Lockwood
2015-06-09 12:25:33 -07:00
parent f4bf80f3ea
commit f88bc3eb73
19 changed files with 753 additions and 423 deletions

View File

@@ -10,6 +10,7 @@
1304D5AB1AA8C4A30002E2BE /* RCTStaticImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5A81AA8C4A30002E2BE /* RCTStaticImage.m */; };
1304D5AC1AA8C4A30002E2BE /* RCTStaticImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5AA1AA8C4A30002E2BE /* RCTStaticImageManager.m */; };
1304D5B21AA8C50D0002E2BE /* RCTGIFImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5B11AA8C50D0002E2BE /* RCTGIFImage.m */; };
1345A8391B26592900583190 /* RCTImageRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 1345A8381B26592900583190 /* RCTImageRequestHandler.m */; };
143879351AAD238D00F088A5 /* RCTCameraRollManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 143879341AAD238D00F088A5 /* RCTCameraRollManager.m */; };
143879381AAD32A300F088A5 /* RCTImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 143879371AAD32A300F088A5 /* RCTImageLoader.m */; };
58B5118F1A9E6BD600147676 /* RCTImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B5118A1A9E6BD600147676 /* RCTImageDownloader.m */; };
@@ -36,6 +37,8 @@
1304D5AA1AA8C4A30002E2BE /* RCTStaticImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStaticImageManager.m; sourceTree = "<group>"; };
1304D5B01AA8C50D0002E2BE /* RCTGIFImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTGIFImage.h; sourceTree = "<group>"; };
1304D5B11AA8C50D0002E2BE /* RCTGIFImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGIFImage.m; sourceTree = "<group>"; };
1345A8371B26592900583190 /* RCTImageRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageRequestHandler.h; sourceTree = "<group>"; };
1345A8381B26592900583190 /* RCTImageRequestHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageRequestHandler.m; sourceTree = "<group>"; };
143879331AAD238D00F088A5 /* RCTCameraRollManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTCameraRollManager.h; sourceTree = "<group>"; };
143879341AAD238D00F088A5 /* RCTCameraRollManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTCameraRollManager.m; sourceTree = "<group>"; };
143879361AAD32A300F088A5 /* RCTImageLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageLoader.h; sourceTree = "<group>"; };
@@ -71,6 +74,8 @@
1304D5B11AA8C50D0002E2BE /* RCTGIFImage.m */,
58B511891A9E6BD600147676 /* RCTImageDownloader.h */,
58B5118A1A9E6BD600147676 /* RCTImageDownloader.m */,
1345A8371B26592900583190 /* RCTImageRequestHandler.h */,
1345A8381B26592900583190 /* RCTImageRequestHandler.m */,
58B5118B1A9E6BD600147676 /* RCTNetworkImageView.h */,
58B5118C1A9E6BD600147676 /* RCTNetworkImageView.m */,
58B5118D1A9E6BD600147676 /* RCTNetworkImageViewManager.h */,
@@ -152,6 +157,7 @@
58B5118F1A9E6BD600147676 /* RCTImageDownloader.m in Sources */,
58B511911A9E6BD600147676 /* RCTNetworkImageViewManager.m in Sources */,
1304D5AC1AA8C4A30002E2BE /* RCTStaticImageManager.m in Sources */,
1345A8391B26592900583190 /* RCTImageRequestHandler.m in Sources */,
58B511901A9E6BD600147676 /* RCTNetworkImageView.m in Sources */,
1304D5B21AA8C50D0002E2BE /* RCTGIFImage.m in Sources */,
143879351AAD238D00F088A5 /* RCTCameraRollManager.m in Sources */,

View File

@@ -23,6 +23,4 @@
+ (void)loadImageWithTag:(NSString *)tag
callback:(void (^)(NSError *error, id /* UIImage or CAAnimation */ image))callback;
+ (BOOL)isSystemImageURI:(NSString *)uri;
@end

View File

@@ -16,11 +16,23 @@
#import <UIKit/UIKit.h>
#import "RCTConvert.h"
#import "RCTDefines.h"
#import "RCTGIFImage.h"
#import "RCTImageDownloader.h"
#import "RCTLog.h"
#import "RCTUtils.h"
static void RCTDispatchCallbackOnMainQueue(void (^ __nonnull callback)(NSError *, id), NSError *error, UIImage *image)
{
if ([NSThread isMainThread]) {
callback(error, image);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
callback(error, image);
});
}
}
static dispatch_queue_t RCTImageLoaderQueue(void)
{
static dispatch_queue_t queue = NULL;
@@ -137,11 +149,4 @@ static dispatch_queue_t RCTImageLoaderQueue(void)
}
}
+ (BOOL)isSystemImageURI:(NSString *)uri
{
return uri != nil && (
[uri hasPrefix:@"assets-library"] ||
[uri hasPrefix:@"ph://"]);
}
@end

View File

@@ -0,0 +1,14 @@
/**
* 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 "RCTURLRequestHandler.h"
@interface RCTImageRequestHandler : NSObject <RCTURLRequestHandler>
@end

View File

@@ -0,0 +1,62 @@
//
// RCTImageRequestHandler.m
// RCTImage
//
// Created by Nick Lockwood on 09/06/2015.
// Copyright (c) 2015 Facebook. All rights reserved.
//
#import "RCTImageRequestHandler.h"
#import <UIKit/UIKit.h>
#import "RCTImageLoader.h"
#import "RCTUtils.h"
@implementation RCTImageRequestHandler
{
NSInteger _currentToken;
}
RCT_EXPORT_MODULE()
- (BOOL)canHandleRequest:(NSURLRequest *)request
{
return [@[@"assets-library", @"ph"] containsObject:[request.URL.scheme lowercaseString]];
}
- (id)sendRequest:(NSURLRequest *)request
withDelegate:(id<RCTURLRequestDelegate>)delegate
{
NSNumber *requestToken = @(++_currentToken);
NSString *URLString = [request.URL absoluteString];
[RCTImageLoader loadImageWithTag:URLString callback:^(NSError *error, UIImage *image) {
if (error) {
[delegate URLRequest:requestToken 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:requestToken didReceiveResponse:response];
[delegate URLRequest:requestToken didReceiveData:imageData];
[delegate URLRequest:requestToken didCompleteWithError:nil];
}];
return requestToken;
}
@end