Refactor hot loading implementation on iOS
Reviewed By: milend Differential Revision: D2795580 fb-gh-sync-id: ad33ba152e40b622b10bfa0122afd6edc28a11bf
This commit is contained in:
parent
54f2586735
commit
ed4478a4ff
|
@ -26,6 +26,7 @@
|
|||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
13B6C1A31C34225900D3FAF5 /* RCTURLUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */; };
|
||||
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DB03471B5D2ED500C27245 /* RCTJSONTests.m */; };
|
||||
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */; };
|
||||
143BC5A11B21E45C00462512 /* UIExplorerSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */; };
|
||||
|
@ -198,6 +199,7 @@
|
|||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = UIExplorer/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = UIExplorer/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = UIExplorer/main.m; sourceTree = "<group>"; };
|
||||
13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTURLUtilsTests.m; sourceTree = "<group>"; };
|
||||
13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
|
||||
13DB03471B5D2ED500C27245 /* RCTJSONTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTJSONTests.m; sourceTree = "<group>"; };
|
||||
13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMethodArgumentTests.m; sourceTree = "<group>"; };
|
||||
|
@ -406,6 +408,7 @@
|
|||
143BC57C1B21E18100462512 /* UIExplorerUnitTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B6C1A21C34225900D3FAF5 /* RCTURLUtilsTests.m */,
|
||||
1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */,
|
||||
1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */,
|
||||
1497CFA61B21F5E400C1F8F2 /* RCTJSCExecutorTests.m */,
|
||||
|
@ -886,6 +889,7 @@
|
|||
1497CFAC1B21F5E400C1F8F2 /* RCTAllocationTests.m in Sources */,
|
||||
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */,
|
||||
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */,
|
||||
13B6C1A31C34225900D3FAF5 /* RCTURLUtilsTests.m in Sources */,
|
||||
8385CF041B87479200C6273E /* RCTImageLoaderHelpers.m in Sources */,
|
||||
8385CEF51B873B5C00C6273E /* RCTImageLoaderTests.m in Sources */,
|
||||
);
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "RCTUtils.h"
|
||||
|
||||
@interface RCTURLUtilsTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTURLUtilsTests
|
||||
|
||||
- (void)testGetQueryParam
|
||||
{
|
||||
NSURL *URL = [NSURL URLWithString:@"http://example.com?foo=bar&bar=foo"];
|
||||
NSString *foo = RCTGetURLQueryParam(URL, @"foo");
|
||||
NSString *bar = RCTGetURLQueryParam(URL, @"bar");
|
||||
XCTAssertEqualObjects(foo, @"bar");
|
||||
XCTAssertEqualObjects(bar, @"foo");
|
||||
}
|
||||
|
||||
- (void)testQueryParamNotFound
|
||||
{
|
||||
NSURL *URL = [NSURL URLWithString:@"http://example.com?foo=bar"];
|
||||
NSString *bar = RCTGetURLQueryParam(URL, @"bar");
|
||||
XCTAssertNil(bar);
|
||||
}
|
||||
|
||||
- (void)testDuplicateParamTakesLatter
|
||||
{
|
||||
NSURL *URL = [NSURL URLWithString:@"http://example.com?foo=bar&foo=foo"];
|
||||
NSString *foo = RCTGetURLQueryParam(URL, @"foo");
|
||||
XCTAssertEqualObjects(foo, @"foo");
|
||||
}
|
||||
|
||||
- (void)testNilURLGetQueryParam
|
||||
{
|
||||
NSURL *URL = nil;
|
||||
NSString *foo = RCTGetURLQueryParam(URL, @"foo");
|
||||
XCTAssertNil(foo);
|
||||
}
|
||||
|
||||
- (void)testReplaceParam
|
||||
{
|
||||
NSURL *URL = [NSURL URLWithString:@"http://example.com?foo=bar&bar=foo"];
|
||||
NSURL *result = RCTURLByReplacingQueryParam(URL, @"foo", @"foo");
|
||||
XCTAssertEqualObjects(result.absoluteString, @"http://example.com?foo=foo&bar=foo");
|
||||
}
|
||||
|
||||
- (void)testAppendParam
|
||||
{
|
||||
NSURL *URL = [NSURL URLWithString:@"http://example.com?bar=foo"];
|
||||
NSURL *result = RCTURLByReplacingQueryParam(URL, @"foo", @"bar");
|
||||
XCTAssertEqualObjects(result.absoluteString, @"http://example.com?bar=foo&foo=bar");
|
||||
}
|
||||
|
||||
- (void)testNilURLAppendQueryParam
|
||||
{
|
||||
NSURL *URL = nil;
|
||||
NSURL *result = RCTURLByReplacingQueryParam(URL, @"foo", @"bar");
|
||||
XCTAssertNil(result);
|
||||
}
|
||||
|
||||
@end
|
|
@ -440,6 +440,16 @@ RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
|
|||
object:_parentBridge userInfo:@{@"bridge": self}];
|
||||
});
|
||||
}];
|
||||
|
||||
#if RCT_DEV
|
||||
|
||||
if (RCTGetURLQueryParam(self.bundleURL, @"hot")) {
|
||||
NSString *path = [self.bundleURL.path substringFromIndex:1]; // strip initial slash
|
||||
[self enqueueJSCall:@"HMRClient.enable" args:@[@"ios", path]];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
- (void)didFinishLoading
|
||||
|
|
|
@ -41,6 +41,11 @@
|
|||
*/
|
||||
@property (nonatomic, copy, readonly) RCTBridgeModuleProviderBlock moduleProvider;
|
||||
|
||||
/**
|
||||
* Used by RCTDevMenu to override the `hot` param of the current bundleURL.
|
||||
*/
|
||||
@property (nonatomic, strong, readwrite) NSURL *bundleURL;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTBridge (RCTBatchedBridge)
|
||||
|
|
|
@ -123,11 +123,11 @@ RCT_EXTERN BOOL RCTBridgeModuleClassIsRegistered(Class);
|
|||
/**
|
||||
* URL of the script that was loaded into the bridge.
|
||||
*/
|
||||
@property (nonatomic, strong) NSURL *bundleURL;
|
||||
@property (nonatomic, strong, readonly) NSURL *bundleURL;
|
||||
|
||||
/**
|
||||
* The class of the executor currently being used *or* to be used after the next
|
||||
* reload.
|
||||
* The class of the executor currently being used. Changes to this value will
|
||||
* take effect after the bridge is reloaded.
|
||||
*/
|
||||
@property (nonatomic, strong) Class executorClass;
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#import "RCTLog.h"
|
||||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTUtils.h"
|
||||
#import "RCTBundleURLProcessor.h"
|
||||
|
||||
NSString *const RCTReloadNotification = @"RCTReloadNotification";
|
||||
NSString *const RCTJavaScriptWillStartLoadingNotification = @"RCTJavaScriptWillStartLoadingNotification";
|
||||
|
@ -88,6 +87,9 @@ BOOL RCTBridgeModuleClassIsRegistered(Class cls)
|
|||
}
|
||||
|
||||
@implementation RCTBridge
|
||||
{
|
||||
NSURL *_delegateBundleURL;
|
||||
}
|
||||
|
||||
dispatch_queue_t RCTJSThread;
|
||||
|
||||
|
@ -257,8 +259,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
{
|
||||
RCTAssertMainThread();
|
||||
|
||||
_bundleURL = [self.delegate sourceURLForBridge:self] ?: _bundleURL;
|
||||
_bundleURL = [[RCTBundleURLProcessor sharedProcessor] process: _bundleURL];
|
||||
// Only update bundleURL from delegate if delegate bundleURL has changed
|
||||
NSURL *previousDelegateURL = _delegateBundleURL;
|
||||
_delegateBundleURL = [self.delegate sourceURLForBridge:self];
|
||||
if (_delegateBundleURL && ![_delegateBundleURL isEqual:previousDelegateURL]) {
|
||||
_bundleURL = _delegateBundleURL;
|
||||
}
|
||||
|
||||
// Sanitize the bundle URL
|
||||
_bundleURL = [RCTConvert NSURL:_bundleURL.absoluteString];
|
||||
|
|
|
@ -48,9 +48,9 @@ typedef void (^RCTSourceLoadBlock)(NSError *error, NSData *source);
|
|||
withBlock:(RCTSourceLoadBlock)loadCallback;
|
||||
|
||||
/**
|
||||
* Indicates wheather Hot Loading is supported or not.
|
||||
* Note this method will get removed soon, once we support Hot Loading on OSS.
|
||||
* Indicates whether Hot Loading is supported or not.
|
||||
* Note: this method will be removed soon, once Hot Loading is supported on OSS.
|
||||
*/
|
||||
- (BOOL)isHotLoadingEnabled;
|
||||
- (BOOL)bridgeSupportsHotLoading:(RCTBridge *)bridge;
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@interface RCTBundleURLProcessor : NSObject
|
||||
|
||||
+ (id)sharedProcessor;
|
||||
|
||||
- (NSString *)getQueryStringValue:(NSString *)attribute;
|
||||
- (void)setQueryStringValue:(NSString *)value forAttribute:(NSString *)attribute;
|
||||
- (NSURL *)process:(NSURL *)url;
|
||||
|
||||
@end
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* 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 <Foundation/Foundation.h>
|
||||
|
||||
#import "RCTBundleURLProcessor.h"
|
||||
|
||||
@implementation RCTBundleURLProcessor
|
||||
|
||||
NSDictionary *_qsAttributes;
|
||||
|
||||
+ (id)sharedProcessor
|
||||
{
|
||||
static RCTBundleURLProcessor *sharedProcessor = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedProcessor = [self new];
|
||||
});
|
||||
return sharedProcessor;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
// dictionary with additional query string attributes that will get appended
|
||||
// to the bundle URL
|
||||
_qsAttributes = [NSMutableDictionary new];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)getQueryStringValue:(NSString *)attribute
|
||||
{
|
||||
return [_qsAttributes valueForKey:attribute];
|
||||
}
|
||||
|
||||
- (void)setQueryStringValue:(NSString *)value forAttribute:(NSString *)attribute
|
||||
{
|
||||
[_qsAttributes setValue:value forKey:attribute];
|
||||
}
|
||||
|
||||
- (NSURL *)process:(NSURL *)url
|
||||
{
|
||||
if (url.isFileURL || [_qsAttributes count] == 0) {
|
||||
return url;
|
||||
}
|
||||
|
||||
// append either `?` or `&` depending on whether there are query string
|
||||
// attibutes or not.
|
||||
NSString *urlString = url.absoluteString;
|
||||
if ([urlString rangeOfString:@"?"].location == NSNotFound) {
|
||||
urlString = [urlString stringByAppendingString:@"?"];
|
||||
} else {
|
||||
urlString = [urlString stringByAppendingString:@"&"];
|
||||
}
|
||||
|
||||
// array with new query string attributes
|
||||
NSMutableArray *parts = [NSMutableArray new];
|
||||
for (id attribute in _qsAttributes) {
|
||||
if ([urlString rangeOfString:[NSString stringWithFormat:@"%@=", attribute]].location != NSNotFound) {
|
||||
[NSException raise:@"Cannot override attribute" format:@"Attribute %@ is already present in url: %@", attribute, url.absoluteString];
|
||||
}
|
||||
[parts addObject:[NSString stringWithFormat:@"%@=%@", attribute, _qsAttributes[attribute]]];
|
||||
}
|
||||
|
||||
return [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", urlString, [parts componentsJoinedByString:@"&"]]];
|
||||
}
|
||||
|
||||
@end
|
|
@ -105,3 +105,7 @@ RCT_EXTERN NSString *RCTColorToHexString(CGColorRef color);
|
|||
|
||||
// Get standard localized string (if it exists)
|
||||
RCT_EXTERN NSString *RCTUIKitLocalizedString(NSString *string);
|
||||
|
||||
// URL manipulation
|
||||
RCT_EXTERN NSString *RCTGetURLQueryParam(NSURL *URL, NSString *param);
|
||||
RCT_EXTERN NSURL *RCTURLByReplacingQueryParam(NSURL *URL, NSString *param, NSString *value);
|
||||
|
|
|
@ -576,10 +576,53 @@ NSString *RCTColorToHexString(CGColorRef color)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// (https://github.com/0xced/XCDFormInputAccessoryView/blob/master/XCDFormInputAccessoryView/XCDFormInputAccessoryView.m#L10-L14)
|
||||
RCT_EXTERN NSString *RCTUIKitLocalizedString(NSString *string)
|
||||
NSString *RCTUIKitLocalizedString(NSString *string)
|
||||
{
|
||||
NSBundle *UIKitBundle = [NSBundle bundleForClass:[UIApplication class]];
|
||||
return UIKitBundle ? [UIKitBundle localizedStringForKey:string value:string table:nil] : string;
|
||||
}
|
||||
|
||||
NSString *RCTGetURLQueryParam(NSURL *URL, NSString *param)
|
||||
{
|
||||
RCTAssertParam(param);
|
||||
if (!URL) {
|
||||
return nil;
|
||||
}
|
||||
NSURLComponents *components = [NSURLComponents componentsWithURL:URL
|
||||
resolvingAgainstBaseURL:YES];
|
||||
for (NSURLQueryItem *item in components.queryItems.reverseObjectEnumerator) {
|
||||
if ([item.name isEqualToString:param]) {
|
||||
return item.value;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSURL *RCTURLByReplacingQueryParam(NSURL *URL, NSString *param, NSString *value)
|
||||
{
|
||||
RCTAssertParam(param);
|
||||
if (!URL) {
|
||||
return nil;
|
||||
}
|
||||
NSURLComponents *components = [NSURLComponents componentsWithURL:URL
|
||||
resolvingAgainstBaseURL:YES];
|
||||
__block NSInteger paramIndex = NSNotFound;
|
||||
NSMutableArray *queryItems = [components.queryItems mutableCopy];
|
||||
[queryItems enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:
|
||||
^(NSURLQueryItem *item, NSUInteger i, BOOL *stop) {
|
||||
if ([item.name isEqualToString:param]) {
|
||||
paramIndex = i;
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
NSURLQueryItem *newItem = [NSURLQueryItem queryItemWithName:param value:value];
|
||||
if (paramIndex == NSNotFound) {
|
||||
[queryItems addObject:newItem];
|
||||
} else {
|
||||
[queryItems replaceObjectAtIndex:paramIndex withObject:newItem];
|
||||
}
|
||||
components.queryItems = queryItems;
|
||||
return components.URL;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,8 @@
|
|||
#import "RCTPerformanceLogger.h"
|
||||
#import "RCTUtils.h"
|
||||
#import "RCTJSCProfiler.h"
|
||||
#import "RCTBundleURLProcessor.h"
|
||||
|
||||
static NSString *const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabled";
|
||||
static NSString *const RCTHotLoadingEnabledDefaultsKey = @"RCTHotLoadingEnabled";
|
||||
|
||||
@interface RCTJavaScriptContext : NSObject <RCTInvalidating>
|
||||
|
||||
|
@ -146,26 +144,6 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL isHotLoadingEnabled()
|
||||
{
|
||||
NSString *enabledQS = [[RCTBundleURLProcessor sharedProcessor] getQueryStringValue:@"hot"];
|
||||
return (enabledQS != nil && [enabledQS isEqualToString:@"true"]) ? YES : NO;
|
||||
}
|
||||
|
||||
static void RCTInstallHotLoading(RCTBridge *bridge, RCTJSCExecutor *executor)
|
||||
{
|
||||
[bridge.devMenu addItem:[RCTDevMenuItem toggleItemWithKey:RCTHotLoadingEnabledDefaultsKey title:@"Enable Hot Loading" selectedTitle:@"Disable Hot Loading" handler:^(BOOL enabledOnCurrentBundle) {
|
||||
[executor executeBlockOnJavaScriptQueue:^{
|
||||
BOOL enabledOnConfig = isHotLoadingEnabled();
|
||||
// reload bundle when user change Hot Loading setting
|
||||
if (enabledOnConfig != enabledOnCurrentBundle) {
|
||||
[[RCTBundleURLProcessor sharedProcessor] setQueryStringValue:enabledOnCurrentBundle ? @"true" : @"false" forAttribute:@"hot"];
|
||||
[bridge reload];
|
||||
}
|
||||
}];
|
||||
}]];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+ (void)runRunLoopThread
|
||||
|
@ -320,10 +298,6 @@ static void RCTInstallHotLoading(RCTBridge *bridge, RCTJSCExecutor *executor)
|
|||
|
||||
RCTInstallJSCProfiler(_bridge, strongSelf->_context.ctx);
|
||||
|
||||
if ([self.bridge.delegate respondsToSelector:@selector(isHotLoadingEnabled)] && [self.bridge.delegate isHotLoadingEnabled]) {
|
||||
RCTInstallHotLoading(_bridge, strongSelf);
|
||||
}
|
||||
|
||||
for (NSString *event in @[RCTProfileDidStartProfiling, RCTProfileDidEndProfiling]) {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:strongSelf
|
||||
selector:@selector(toggleProfilingFlag:)
|
||||
|
@ -535,13 +509,6 @@ static void RCTInstallHotLoading(RCTBridge *bridge, RCTJSCExecutor *executor)
|
|||
onComplete(error);
|
||||
}
|
||||
}), 0, @"js_call", (@{ @"url": sourceURL.absoluteString }))];
|
||||
|
||||
#if RCT_DEV
|
||||
if (isHotLoadingEnabled()) {
|
||||
// strip initial slash
|
||||
[_bridge enqueueJSCall:@"HMRClient.enable" args:@[@"ios", [sourceURL.path substringFromIndex: 1]]];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block
|
||||
|
|
|
@ -36,6 +36,11 @@
|
|||
*/
|
||||
@property (nonatomic, assign) BOOL liveReloadEnabled;
|
||||
|
||||
/**
|
||||
* Enables hot loading. Currently not supported in open source.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL hotLoadingEnabled;
|
||||
|
||||
/**
|
||||
* Shows the FPS monitor for the JS and Main threads.
|
||||
*/
|
||||
|
|
|
@ -267,6 +267,7 @@ RCT_EXPORT_MODULE()
|
|||
self.shakeToShow = [_settings[@"shakeToShow"] ?: @YES boolValue];
|
||||
self.profilingEnabled = [_settings[@"profilingEnabled"] ?: @NO boolValue];
|
||||
self.liveReloadEnabled = [_settings[@"liveReloadEnabled"] ?: @NO boolValue];
|
||||
self.hotLoadingEnabled = [_settings[@"hotLoadingEnabled"] ?: @YES boolValue];
|
||||
self.showFPS = [_settings[@"showFPS"] ?: @NO boolValue];
|
||||
self.executorClass = NSClassFromString(_executorOverride ?: _settings[@"executorClass"]);
|
||||
}
|
||||
|
@ -321,7 +322,7 @@ RCT_EXPORT_MODULE()
|
|||
} else {
|
||||
RCTLogWarn(@"RCTSourceCode module scriptURL has not been set");
|
||||
}
|
||||
} else if (!(sourceCodeModule.scriptURL).fileURL) {
|
||||
} else if (!sourceCodeModule.scriptURL.fileURL) {
|
||||
// Live reloading is disabled when running from bundled JS file
|
||||
_liveReloadURL = [[NSURL alloc] initWithString:@"/onchange" relativeToURL:sourceCodeModule.scriptURL];
|
||||
}
|
||||
|
@ -420,6 +421,13 @@ RCT_EXPORT_MODULE()
|
|||
}]];
|
||||
}
|
||||
|
||||
if ([self hotLoadingAvailable]) {
|
||||
NSString *hotLoadingTitle = _hotLoadingEnabled ? @"Disable Hot Loading" : @"Enable Hot Loading";
|
||||
[items addObject:[RCTDevMenuItem buttonItemWithTitle:hotLoadingTitle handler:^{
|
||||
weakSelf.hotLoadingEnabled = !_hotLoadingEnabled;
|
||||
}]];
|
||||
}
|
||||
|
||||
[items addObjectsFromArray:_extraMenuItems];
|
||||
|
||||
return items;
|
||||
|
@ -483,8 +491,6 @@ RCT_EXPORT_METHOD(show)
|
|||
|
||||
RCT_EXPORT_METHOD(reload)
|
||||
{
|
||||
_jsLoaded = NO;
|
||||
_liveReloadURL = nil;
|
||||
[_bridge reload];
|
||||
}
|
||||
|
||||
|
@ -523,6 +529,26 @@ RCT_EXPORT_METHOD(reload)
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)hotLoadingAvailable
|
||||
{
|
||||
return !_bridge.bundleURL.fileURL // Only works when running from server
|
||||
&& [_bridge.delegate respondsToSelector:@selector(bridgeSupportsHotLoading:)]
|
||||
&& [_bridge.delegate bridgeSupportsHotLoading:_bridge];
|
||||
}
|
||||
|
||||
- (void)setHotLoadingEnabled:(BOOL)enabled
|
||||
{
|
||||
_hotLoadingEnabled = enabled;
|
||||
[self updateSetting:@"hotLoadingEnabled" value:@(_hotLoadingEnabled)];
|
||||
|
||||
BOOL actuallyEnabled = [self hotLoadingAvailable] && _hotLoadingEnabled;
|
||||
if (RCTGetURLQueryParam(_bridge.bundleURL, @"hot").boolValue != actuallyEnabled) {
|
||||
_bridge.bundleURL = RCTURLByReplacingQueryParam(_bridge.bundleURL, @"hot",
|
||||
actuallyEnabled ? @"true" : @"false");
|
||||
[_bridge reload];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setExecutorClass:(Class)executorClass
|
||||
{
|
||||
if (_executorClass != executorClass) {
|
||||
|
@ -543,7 +569,7 @@ RCT_EXPORT_METHOD(reload)
|
|||
}
|
||||
|
||||
_bridge.executorClass = executorClass;
|
||||
[self reload];
|
||||
[_bridge reload];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
14F484561AABFCE100FDF6B9 /* RCTSliderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F484551AABFCE100FDF6B9 /* RCTSliderManager.m */; };
|
||||
14F7A0EC1BDA3B3C003C6C10 /* RCTPerfMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EB1BDA3B3C003C6C10 /* RCTPerfMonitor.m */; };
|
||||
14F7A0F01BDA714B003C6C10 /* RCTFPSGraph.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EF1BDA714B003C6C10 /* RCTFPSGraph.m */; };
|
||||
1BCBD4A71C32FA0B006FC476 /* RCTBundleURLProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BCBD4A61C32FA0B006FC476 /* RCTBundleURLProcessor.m */; };
|
||||
191E3EBE1C29D9AF00C180A6 /* RCTRefreshControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 191E3EBD1C29D9AF00C180A6 /* RCTRefreshControlManager.m */; };
|
||||
191E3EC11C29DC3800C180A6 /* RCTRefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 191E3EC01C29DC3800C180A6 /* RCTRefreshControl.m */; };
|
||||
58114A161AAE854800E7D092 /* RCTPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 58114A131AAE854800E7D092 /* RCTPicker.m */; };
|
||||
|
@ -245,8 +244,6 @@
|
|||
14F7A0EB1BDA3B3C003C6C10 /* RCTPerfMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPerfMonitor.m; sourceTree = "<group>"; };
|
||||
14F7A0EE1BDA714B003C6C10 /* RCTFPSGraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTFPSGraph.h; sourceTree = "<group>"; };
|
||||
14F7A0EF1BDA714B003C6C10 /* RCTFPSGraph.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTFPSGraph.m; sourceTree = "<group>"; };
|
||||
1BCBD4A51C32FA0B006FC476 /* RCTBundleURLProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBundleURLProcessor.h; sourceTree = "<group>"; };
|
||||
1BCBD4A61C32FA0B006FC476 /* RCTBundleURLProcessor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBundleURLProcessor.m; sourceTree = "<group>"; };
|
||||
191E3EBC1C29D9AF00C180A6 /* RCTRefreshControlManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRefreshControlManager.h; sourceTree = "<group>"; };
|
||||
191E3EBD1C29D9AF00C180A6 /* RCTRefreshControlManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRefreshControlManager.m; sourceTree = "<group>"; };
|
||||
191E3EBF1C29DC3800C180A6 /* RCTRefreshControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRefreshControl.h; sourceTree = "<group>"; };
|
||||
|
@ -526,8 +523,6 @@
|
|||
83CBBA651A601EF300E9B192 /* RCTEventDispatcher.h */,
|
||||
83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */,
|
||||
1436DD071ADE7AA000A5ED7D /* RCTFrameUpdate.h */,
|
||||
1BCBD4A51C32FA0B006FC476 /* RCTBundleURLProcessor.h */,
|
||||
1BCBD4A61C32FA0B006FC476 /* RCTBundleURLProcessor.m */,
|
||||
14C2CA751B3AC64F00E6CBB2 /* RCTFrameUpdate.m */,
|
||||
83CBBA4C1A601E3B00E9B192 /* RCTInvalidating.h */,
|
||||
83CBBA631A601ECA00E9B192 /* RCTJavaScriptExecutor.h */,
|
||||
|
@ -687,7 +682,6 @@
|
|||
13E41EEB1C05CA0B00CD8DAC /* RCTProfileTrampoline-i386.S in Sources */,
|
||||
13B080061A6947C200A75B9A /* RCTScrollViewManager.m in Sources */,
|
||||
14200DAA1AC179B3008EE6BA /* RCTJavaScriptLoader.m in Sources */,
|
||||
1BCBD4A71C32FA0B006FC476 /* RCTBundleURLProcessor.m in Sources */,
|
||||
137327EA1AA5CF210034F82E /* RCTTabBarManager.m in Sources */,
|
||||
13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */,
|
||||
13B080051A6947C200A75B9A /* RCTScrollView.m in Sources */,
|
||||
|
|
Loading…
Reference in New Issue