Show packager progress in UI
Reviewed By: javache Differential Revision: D3941904 fbshipit-source-id: 4ea3b61e9d636eeaddbadbe4ba6c62069955f022
This commit is contained in:
parent
ef91708fdb
commit
5f548e15f9
|
@ -73,9 +73,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
||||||
withBlock:(RCTSourceLoadBlock)loadCallback
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
||||||
|
onComplete:(RCTSourceLoadBlock)loadCallback
|
||||||
{
|
{
|
||||||
[RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge]
|
[RCTJavaScriptLoader loadBundleAtURL:[self sourceURLForBridge:bridge]
|
||||||
|
onProgress:onProgress
|
||||||
onComplete:loadCallback];
|
onComplete:loadCallback];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#import "RCTSourceCode.h"
|
#import "RCTSourceCode.h"
|
||||||
#import "RCTUtils.h"
|
#import "RCTUtils.h"
|
||||||
#import "RCTRedBox.h"
|
#import "RCTRedBox.h"
|
||||||
|
#import "RCTDevLoadingView.h"
|
||||||
|
|
||||||
#define RCTAssertJSThread() \
|
#define RCTAssertJSThread() \
|
||||||
RCTAssert(![NSStringFromClass([self->_javaScriptExecutor class]) isEqualToString:@"RCTJSCExecutor"] || \
|
RCTAssert(![NSStringFromClass([self->_javaScriptExecutor class]) isEqualToString:@"RCTJSCExecutor"] || \
|
||||||
|
@ -115,6 +116,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)dele
|
||||||
|
|
||||||
sourceCode = source;
|
sourceCode = source;
|
||||||
dispatch_group_leave(initModulesAndLoadSource);
|
dispatch_group_leave(initModulesAndLoadSource);
|
||||||
|
} onProgress:^(RCTLoadingProgress *progressData) {
|
||||||
|
#ifdef RCT_DEV
|
||||||
|
RCTDevLoadingView *loadingView = [weakSelf moduleForClass:[RCTDevLoadingView class]];
|
||||||
|
[loadingView updateProgress:progressData];
|
||||||
|
#endif
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// Synchronously initialize all native modules that cannot be loaded lazily
|
// Synchronously initialize all native modules that cannot be loaded lazily
|
||||||
|
@ -172,7 +178,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)dele
|
||||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadSource:(RCTSourceLoadBlock)_onSourceLoad
|
- (void)loadSource:(RCTSourceLoadBlock)_onSourceLoad onProgress:(RCTSourceLoadProgressBlock)onProgress
|
||||||
{
|
{
|
||||||
[_performanceLogger markStartForTag:RCTPLScriptDownload];
|
[_performanceLogger markStartForTag:RCTPLScriptDownload];
|
||||||
|
|
||||||
|
@ -183,18 +189,20 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)dele
|
||||||
_onSourceLoad(error, source, sourceLength);
|
_onSourceLoad(error, source, sourceLength);
|
||||||
};
|
};
|
||||||
|
|
||||||
if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:withBlock:)]) {
|
if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:onProgress:onComplete:)]) {
|
||||||
|
[self.delegate loadSourceForBridge:_parentBridge onProgress:onProgress onComplete:onSourceLoad];
|
||||||
|
} else if ([self.delegate respondsToSelector:@selector(loadSourceForBridge:withBlock:)]) {
|
||||||
[self.delegate loadSourceForBridge:_parentBridge withBlock:onSourceLoad];
|
[self.delegate loadSourceForBridge:_parentBridge withBlock:onSourceLoad];
|
||||||
} else {
|
} else {
|
||||||
RCTAssert(self.bundleURL, @"bundleURL must be non-nil when not implementing loadSourceForBridge");
|
RCTAssert(self.bundleURL, @"bundleURL must be non-nil when not implementing loadSourceForBridge");
|
||||||
|
|
||||||
[RCTJavaScriptLoader loadBundleAtURL:self.bundleURL onComplete:^(NSError *error, NSData *source, int64_t sourceLength) {
|
[RCTJavaScriptLoader loadBundleAtURL:self.bundleURL onProgress:onProgress onComplete:^(NSError *error, NSData *source, int64_t sourceLength) {
|
||||||
if (error && [self.delegate respondsToSelector:@selector(fallbackSourceURLForBridge:)]) {
|
if (error && [self.delegate respondsToSelector:@selector(fallbackSourceURLForBridge:)]) {
|
||||||
NSURL *fallbackURL = [self.delegate fallbackSourceURLForBridge:self->_parentBridge];
|
NSURL *fallbackURL = [self.delegate fallbackSourceURLForBridge:self->_parentBridge];
|
||||||
if (fallbackURL && ![fallbackURL isEqual:self.bundleURL]) {
|
if (fallbackURL && ![fallbackURL isEqual:self.bundleURL]) {
|
||||||
RCTLogError(@"Failed to load bundle(%@) with error:(%@)", self.bundleURL, error.localizedDescription);
|
RCTLogError(@"Failed to load bundle(%@) with error:(%@)", self.bundleURL, error.localizedDescription);
|
||||||
self.bundleURL = fallbackURL;
|
self.bundleURL = fallbackURL;
|
||||||
[RCTJavaScriptLoader loadBundleAtURL:self.bundleURL onComplete:onSourceLoad];
|
[RCTJavaScriptLoader loadBundleAtURL:self.bundleURL onProgress:onProgress onComplete:onSourceLoad];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,14 @@
|
||||||
* location specified by the `sourceURLForBridge:` method, however, if you want
|
* location specified by the `sourceURLForBridge:` method, however, if you want
|
||||||
* to handle loading the JS yourself, you can do so by implementing this method.
|
* to handle loading the JS yourself, you can do so by implementing this method.
|
||||||
*/
|
*/
|
||||||
|
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
||||||
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
||||||
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to loadSourceForBridge:onProgress:onComplete: but without progress
|
||||||
|
* reporting.
|
||||||
|
*/
|
||||||
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
||||||
withBlock:(RCTSourceLoadBlock)loadCallback;
|
withBlock:(RCTSourceLoadBlock)loadCallback;
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,20 @@ NS_ENUM(NSInteger) {
|
||||||
RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously = 1000,
|
RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously = 1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@interface RCTLoadingProgress : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NSString *status;
|
||||||
|
@property (strong, nonatomic) NSNumber *done;
|
||||||
|
@property (strong, nonatomic) NSNumber *total;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
typedef void (^RCTSourceLoadProgressBlock)(RCTLoadingProgress *progressData);
|
||||||
typedef void (^RCTSourceLoadBlock)(NSError *error, NSData *source, int64_t sourceLength);
|
typedef void (^RCTSourceLoadBlock)(NSError *error, NSData *source, int64_t sourceLength);
|
||||||
|
|
||||||
@interface RCTJavaScriptLoader : NSObject
|
@interface RCTJavaScriptLoader : NSObject
|
||||||
|
|
||||||
+ (void)loadBundleAtURL:(NSURL *)scriptURL onComplete:(RCTSourceLoadBlock)onComplete;
|
+ (void)loadBundleAtURL:(NSURL *)scriptURL onProgress:(RCTSourceLoadProgressBlock)onProgress onComplete:(RCTSourceLoadBlock)onComplete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @experimental
|
* @experimental
|
||||||
|
|
|
@ -22,11 +22,27 @@ uint32_t const RCTRAMBundleMagicNumber = 0xFB0BD1E5;
|
||||||
|
|
||||||
NSString *const RCTJavaScriptLoaderErrorDomain = @"RCTJavaScriptLoaderErrorDomain";
|
NSString *const RCTJavaScriptLoaderErrorDomain = @"RCTJavaScriptLoaderErrorDomain";
|
||||||
|
|
||||||
|
@implementation RCTLoadingProgress
|
||||||
|
|
||||||
|
- (NSString *)description
|
||||||
|
{
|
||||||
|
NSMutableString *desc = [NSMutableString new];
|
||||||
|
[desc appendString:_status ?: @"Loading"];
|
||||||
|
|
||||||
|
if (_total > 0) {
|
||||||
|
[desc appendFormat:@" %ld%% (%@/%@)", (long)(100 * [_done integerValue] / [_total integerValue]), _done, _total];
|
||||||
|
}
|
||||||
|
[desc appendString:@"…"];
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation RCTJavaScriptLoader
|
@implementation RCTJavaScriptLoader
|
||||||
|
|
||||||
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||||
|
|
||||||
+ (void)loadBundleAtURL:(NSURL *)scriptURL onComplete:(RCTSourceLoadBlock)onComplete
|
+ (void)loadBundleAtURL:(NSURL *)scriptURL onProgress:(RCTSourceLoadProgressBlock)onProgress onComplete:(RCTSourceLoadBlock)onComplete
|
||||||
{
|
{
|
||||||
int64_t sourceLength;
|
int64_t sourceLength;
|
||||||
NSError *error;
|
NSError *error;
|
||||||
|
@ -43,7 +59,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||||
&& error.code == RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously;
|
&& error.code == RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously;
|
||||||
|
|
||||||
if (isCannotLoadSyncError) {
|
if (isCannotLoadSyncError) {
|
||||||
attemptAsynchronousLoadOfBundleAtURL(scriptURL, onComplete);
|
attemptAsynchronousLoadOfBundleAtURL(scriptURL, onProgress, onComplete);
|
||||||
} else {
|
} else {
|
||||||
onComplete(error, nil, 0);
|
onComplete(error, nil, 0);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +152,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||||
return [NSData dataWithBytes:&magicNumber length:sizeof(magicNumber)];
|
return [NSData dataWithBytes:&magicNumber length:sizeof(magicNumber)];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void attemptAsynchronousLoadOfBundleAtURL(NSURL *scriptURL, RCTSourceLoadBlock onComplete)
|
static void attemptAsynchronousLoadOfBundleAtURL(NSURL *scriptURL, RCTSourceLoadProgressBlock onProgress, RCTSourceLoadBlock onComplete)
|
||||||
{
|
{
|
||||||
scriptURL = sanitizeURL(scriptURL);
|
scriptURL = sanitizeURL(scriptURL);
|
||||||
|
|
||||||
|
@ -155,7 +171,9 @@ static void attemptAsynchronousLoadOfBundleAtURL(NSURL *scriptURL, RCTSourceLoad
|
||||||
|
|
||||||
RCTMultipartDataTask *task = [[RCTMultipartDataTask alloc] initWithURL:scriptURL partHandler:^(NSInteger statusCode, NSDictionary *headers, NSData *data, NSError *error, BOOL done) {
|
RCTMultipartDataTask *task = [[RCTMultipartDataTask alloc] initWithURL:scriptURL partHandler:^(NSInteger statusCode, NSDictionary *headers, NSData *data, NSError *error, BOOL done) {
|
||||||
if (!done) {
|
if (!done) {
|
||||||
// TODO(frantic): Emit progress event
|
if (onProgress) {
|
||||||
|
onProgress(progressEventFromData(data));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +224,21 @@ static NSURL *sanitizeURL(NSURL *url)
|
||||||
return [RCTConvert NSURL:url.absoluteString];
|
return [RCTConvert NSURL:url.absoluteString];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static RCTLoadingProgress *progressEventFromData(NSData *rawData)
|
||||||
|
{
|
||||||
|
NSString *text = [[NSString alloc] initWithData:rawData encoding:NSUTF8StringEncoding];
|
||||||
|
id info = RCTJSONParse(text, nil);
|
||||||
|
if (!info || ![info isKindOfClass:[NSDictionary class]]) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCTLoadingProgress *progress = [RCTLoadingProgress new];
|
||||||
|
progress.status = [info valueForKey:@"status"];
|
||||||
|
progress.done = [info valueForKey:@"done"];
|
||||||
|
progress.total = [info valueForKey:@"total"];
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
static NSDictionary *userInfoForRawResponse(NSString *rawText)
|
static NSDictionary *userInfoForRawResponse(NSString *rawText)
|
||||||
{
|
{
|
||||||
NSDictionary *parsedResponse = RCTJSONParse(rawText, nil);
|
NSDictionary *parsedResponse = RCTJSONParse(rawText, nil);
|
||||||
|
|
|
@ -12,5 +12,6 @@
|
||||||
@interface RCTDevLoadingView : NSObject <RCTBridgeModule>
|
@interface RCTDevLoadingView : NSObject <RCTBridgeModule>
|
||||||
|
|
||||||
+ (void)setEnabled:(BOOL)enabled;
|
+ (void)setEnabled:(BOOL)enabled;
|
||||||
|
- (void)updateProgress:(RCTLoadingProgress *)progress;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -142,6 +142,16 @@ RCT_EXPORT_METHOD(hide)
|
||||||
backgroundColor:backgroundColor];
|
backgroundColor:backgroundColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateProgress:(RCTLoadingProgress *)progress
|
||||||
|
{
|
||||||
|
if (!progress) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
self->_label.text = [progress description];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -150,6 +160,7 @@ RCT_EXPORT_METHOD(hide)
|
||||||
|
|
||||||
+ (NSString *)moduleName { return nil; }
|
+ (NSString *)moduleName { return nil; }
|
||||||
+ (void)setEnabled:(BOOL)enabled { }
|
+ (void)setEnabled:(BOOL)enabled { }
|
||||||
|
- (void)updateProgress:(RCTLoadingProgress *)progress {}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue