Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
/**
|
|
|
|
* 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 "RCTDevSettings.h"
|
|
|
|
|
|
|
|
#import <objc/runtime.h>
|
|
|
|
|
|
|
|
#import <JavaScriptCore/JavaScriptCore.h>
|
|
|
|
|
|
|
|
#import <jschelpers/JavaScriptCore.h>
|
|
|
|
|
|
|
|
#import "RCTBridge+Private.h"
|
|
|
|
#import "RCTBridgeModule.h"
|
|
|
|
#import "RCTEventDispatcher.h"
|
2017-04-18 20:15:25 +00:00
|
|
|
#import "RCTJSCSamplingProfiler.h"
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
#import "RCTLog.h"
|
2017-11-21 02:12:13 +00:00
|
|
|
#import "RCTPackagerClient.h"
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
#import "RCTProfile.h"
|
|
|
|
#import "RCTUtils.h"
|
|
|
|
|
2017-07-25 11:40:19 +00:00
|
|
|
static NSString *const kRCTDevSettingProfilingEnabled = @"profilingEnabled";
|
|
|
|
static NSString *const kRCTDevSettingHotLoadingEnabled = @"hotLoadingEnabled";
|
|
|
|
static NSString *const kRCTDevSettingLiveReloadEnabled = @"liveReloadEnabled";
|
|
|
|
static NSString *const kRCTDevSettingIsInspectorShown = @"showInspector";
|
|
|
|
static NSString *const kRCTDevSettingIsDebuggingRemotely = @"isDebuggingRemotely";
|
|
|
|
static NSString *const kRCTDevSettingExecutorOverrideClass = @"executor-override";
|
|
|
|
static NSString *const kRCTDevSettingShakeToShowDevMenu = @"shakeToShow";
|
|
|
|
static NSString *const kRCTDevSettingIsPerfMonitorShown = @"RCTPerfMonitorKey";
|
|
|
|
static NSString *const kRCTDevSettingStartSamplingProfilerOnLaunch = @"startSamplingProfilerOnLaunch";
|
|
|
|
|
|
|
|
static NSString *const kRCTDevSettingsUserDefaultsKey = @"RCTDevMenu";
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
|
2017-04-20 15:20:03 +00:00
|
|
|
#if ENABLE_PACKAGER_CONNECTION
|
|
|
|
#import "RCTPackagerConnection.h"
|
2017-02-27 21:25:47 +00:00
|
|
|
#endif
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
|
2017-08-24 17:39:13 +00:00
|
|
|
#if RCT_ENABLE_INSPECTOR
|
2017-07-07 09:29:23 +00:00
|
|
|
#import "RCTInspectorDevServerHelper.h"
|
2017-12-14 16:12:21 +00:00
|
|
|
#import <jschelpers/JSCWrapper.h>
|
2017-07-07 09:29:23 +00:00
|
|
|
#endif
|
|
|
|
|
2017-04-20 15:20:03 +00:00
|
|
|
#if RCT_DEV
|
|
|
|
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
@interface RCTDevSettingsUserDefaultsDataSource : NSObject <RCTDevSettingsDataSource>
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RCTDevSettingsUserDefaultsDataSource {
|
|
|
|
NSMutableDictionary *_settings;
|
|
|
|
NSUserDefaults *_userDefaults;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)init
|
|
|
|
{
|
|
|
|
return [self initWithDefaultValues:nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)initWithDefaultValues:(NSDictionary *)defaultValues
|
|
|
|
{
|
|
|
|
if (self = [super init]) {
|
|
|
|
_userDefaults = [NSUserDefaults standardUserDefaults];
|
|
|
|
if (defaultValues) {
|
|
|
|
[self _reloadWithDefaults:defaultValues];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)updateSettingWithValue:(id)value forKey:(NSString *)key
|
|
|
|
{
|
|
|
|
RCTAssert((key != nil), @"%@", [NSString stringWithFormat:@"%@: Tried to update nil key", [self class]]);
|
|
|
|
|
|
|
|
id currentValue = [self settingForKey:key];
|
|
|
|
if (currentValue == value || [currentValue isEqual:value]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (value) {
|
|
|
|
_settings[key] = value;
|
|
|
|
} else {
|
|
|
|
[_settings removeObjectForKey:key];
|
|
|
|
}
|
|
|
|
[_userDefaults setObject:_settings forKey:kRCTDevSettingsUserDefaultsKey];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id)settingForKey:(NSString *)key
|
|
|
|
{
|
|
|
|
return _settings[key];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_reloadWithDefaults:(NSDictionary *)defaultValues
|
|
|
|
{
|
|
|
|
NSDictionary *existingSettings = [_userDefaults objectForKey:kRCTDevSettingsUserDefaultsKey];
|
|
|
|
_settings = existingSettings ? [existingSettings mutableCopy] : [NSMutableDictionary dictionary];
|
|
|
|
for (NSString *key in [defaultValues keyEnumerator]) {
|
|
|
|
if (!_settings[key]) {
|
|
|
|
_settings[key] = defaultValues[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[_userDefaults setObject:_settings forKey:kRCTDevSettingsUserDefaultsKey];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@interface RCTDevSettings () <RCTBridgeModule, RCTInvalidating>
|
|
|
|
{
|
|
|
|
NSURLSessionDataTask *_liveReloadUpdateTask;
|
|
|
|
NSURL *_liveReloadURL;
|
|
|
|
BOOL _isJSLoaded;
|
2017-04-20 15:20:03 +00:00
|
|
|
#if ENABLE_PACKAGER_CONNECTION
|
2017-11-21 02:12:13 +00:00
|
|
|
RCTHandlerToken _reloadToken;
|
|
|
|
RCTHandlerToken _pokeSamplingProfilerToken;
|
2017-04-20 15:20:03 +00:00
|
|
|
#endif
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@property (nonatomic, strong) Class executorClass;
|
|
|
|
@property (nonatomic, readwrite, strong) id<RCTDevSettingsDataSource> dataSource;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RCTDevSettings
|
|
|
|
|
|
|
|
@synthesize bridge = _bridge;
|
|
|
|
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
|
2017-08-07 13:45:24 +00:00
|
|
|
+ (BOOL)requiresMainQueueSetup
|
|
|
|
{
|
|
|
|
return YES; // RCT_DEV-only
|
|
|
|
}
|
|
|
|
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
- (instancetype)init
|
|
|
|
{
|
|
|
|
// default behavior is to use NSUserDefaults
|
|
|
|
NSDictionary *defaultValues = @{
|
|
|
|
kRCTDevSettingShakeToShowDevMenu: @YES,
|
|
|
|
};
|
|
|
|
RCTDevSettingsUserDefaultsDataSource *dataSource = [[RCTDevSettingsUserDefaultsDataSource alloc] initWithDefaultValues:defaultValues];
|
|
|
|
return [self initWithDataSource:dataSource];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)initWithDataSource:(id<RCTDevSettingsDataSource>)dataSource
|
|
|
|
{
|
|
|
|
if (self = [super init]) {
|
|
|
|
_dataSource = dataSource;
|
2017-05-05 15:32:15 +00:00
|
|
|
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(jsLoaded:)
|
|
|
|
name:RCTJavaScriptDidLoadNotification
|
|
|
|
object:nil];
|
|
|
|
|
|
|
|
// Delay setup until after Bridge init
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
[self _synchronizeAllSettings];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2017-05-15 17:16:39 +00:00
|
|
|
- (void)setBridge:(RCTBridge *)bridge
|
|
|
|
{
|
|
|
|
RCTAssert(_bridge == nil, @"RCTDevSettings module should not be reused");
|
|
|
|
_bridge = bridge;
|
2017-11-21 02:12:13 +00:00
|
|
|
|
|
|
|
#if ENABLE_PACKAGER_CONNECTION
|
|
|
|
RCTBridge *__weak weakBridge = bridge;
|
|
|
|
_reloadToken =
|
|
|
|
[[RCTPackagerConnection sharedPackagerConnection]
|
|
|
|
addNotificationHandler:^(id params) {
|
|
|
|
if (params != (id)kCFNull && [params[@"debug"] boolValue]) {
|
|
|
|
weakBridge.executorClass = objc_lookUpClass("RCTWebSocketExecutor");
|
|
|
|
}
|
|
|
|
[weakBridge reload];
|
|
|
|
}
|
|
|
|
queue:dispatch_get_main_queue()
|
|
|
|
forMethod:@"reload"];
|
|
|
|
|
|
|
|
_pokeSamplingProfilerToken =
|
|
|
|
[[RCTPackagerConnection sharedPackagerConnection]
|
|
|
|
addRequestHandler:^(NSDictionary<NSString *, id> *params, RCTPackagerClientResponder *responder) {
|
|
|
|
pokeSamplingProfiler(weakBridge, responder);
|
|
|
|
}
|
|
|
|
queue:dispatch_get_main_queue()
|
|
|
|
forMethod:@"pokeSamplingProfiler"];
|
|
|
|
#endif
|
2017-06-08 14:34:45 +00:00
|
|
|
|
2017-09-07 11:40:23 +00:00
|
|
|
#if RCT_ENABLE_INSPECTOR
|
2017-06-08 14:34:45 +00:00
|
|
|
// we need this dispatch back to the main thread because even though this
|
|
|
|
// is executed on the main thread, at this point the bridge is not yet
|
|
|
|
// finished with its initialisation. But it does finish by the time it
|
|
|
|
// relinquishes control of the main thread, so only queue on the JS thread
|
|
|
|
// after the current main thread operation is done.
|
2017-12-18 21:19:39 +00:00
|
|
|
if (self.isNuclideDebuggingAvailable) {
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
[bridge dispatchBlock:^{
|
|
|
|
[RCTInspectorDevServerHelper connectWithBundleURL:bridge.bundleURL];
|
|
|
|
} queue:RCTJSThread];
|
|
|
|
});
|
|
|
|
}
|
2017-06-08 14:34:45 +00:00
|
|
|
#endif
|
2017-05-15 17:16:39 +00:00
|
|
|
}
|
|
|
|
|
2017-11-21 02:12:13 +00:00
|
|
|
static void pokeSamplingProfiler(RCTBridge *const bridge, RCTPackagerClientResponder *const responder)
|
|
|
|
{
|
|
|
|
if (!bridge) {
|
|
|
|
[responder respondWithError:@"The bridge is nil. Try again."];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSGlobalContextRef globalContext = bridge.jsContextRef;
|
|
|
|
if (!JSC_JSSamplingProfilerEnabled(globalContext)) {
|
|
|
|
[responder respondWithError:@"The JSSamplingProfiler is disabled. See 'iOS specific setup' section here https://fburl.com/u4lw7xeq for some help"];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// JSPokeSamplingProfiler() toggles the profiling process
|
|
|
|
JSValueRef jsResult = JSC_JSPokeSamplingProfiler(globalContext);
|
|
|
|
if (JSC_JSValueGetType(globalContext, jsResult) == kJSTypeNull) {
|
|
|
|
[responder respondWithResult:@"started"];
|
|
|
|
} else {
|
|
|
|
JSContext *context = [JSC_JSContext(globalContext) contextWithJSGlobalContextRef:globalContext];
|
|
|
|
NSString *results = [[JSC_JSValue(globalContext) valueWithJSValueRef:jsResult inContext:context] toObject];
|
|
|
|
[responder respondWithResult:results];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
- (dispatch_queue_t)methodQueue
|
|
|
|
{
|
|
|
|
return dispatch_get_main_queue();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)invalidate
|
|
|
|
{
|
|
|
|
[_liveReloadUpdateTask cancel];
|
2017-11-21 02:12:13 +00:00
|
|
|
#if ENABLE_PACKAGER_CONNECTION
|
|
|
|
[[RCTPackagerConnection sharedPackagerConnection] removeHandler:_reloadToken];
|
|
|
|
[[RCTPackagerConnection sharedPackagerConnection] removeHandler:_pokeSamplingProfilerToken];
|
|
|
|
#endif
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_updateSettingWithValue:(id)value forKey:(NSString *)key
|
|
|
|
{
|
|
|
|
[_dataSource updateSettingWithValue:value forKey:key];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id)settingForKey:(NSString *)key
|
|
|
|
{
|
|
|
|
return [_dataSource settingForKey:key];
|
|
|
|
}
|
|
|
|
|
2017-12-05 14:27:32 +00:00
|
|
|
- (BOOL)isNuclideDebuggingAvailable
|
|
|
|
{
|
|
|
|
#if RCT_ENABLE_INSPECTOR
|
2017-12-18 21:19:39 +00:00
|
|
|
return _bridge.isInspectable;
|
2017-12-05 14:27:32 +00:00
|
|
|
#else
|
|
|
|
return false;
|
2017-12-18 21:19:39 +00:00
|
|
|
#endif // RCT_ENABLE_INSPECTOR
|
2017-12-05 14:27:32 +00:00
|
|
|
}
|
|
|
|
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
- (BOOL)isRemoteDebuggingAvailable
|
|
|
|
{
|
|
|
|
Class jsDebuggingExecutorClass = objc_lookUpClass("RCTWebSocketExecutor");
|
|
|
|
return (jsDebuggingExecutorClass != nil);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isHotLoadingAvailable
|
|
|
|
{
|
|
|
|
return _bridge.bundleURL && !_bridge.bundleURL.fileURL; // Only works when running from server
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isLiveReloadAvailable
|
|
|
|
{
|
|
|
|
return (_liveReloadURL != nil);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isJSCSamplingProfilerAvailable
|
|
|
|
{
|
2017-04-07 18:11:04 +00:00
|
|
|
return JSC_JSSamplingProfilerEnabled(_bridge.jsContextRef);
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(reload)
|
|
|
|
{
|
|
|
|
[_bridge reload];
|
|
|
|
}
|
|
|
|
|
2017-04-21 09:54:09 +00:00
|
|
|
RCT_EXPORT_METHOD(setIsShakeToShowDevMenuEnabled:(BOOL)enabled)
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
{
|
2017-04-21 09:54:09 +00:00
|
|
|
[self _updateSettingWithValue:@(enabled) forKey:kRCTDevSettingShakeToShowDevMenu];
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isShakeToShowDevMenuEnabled
|
|
|
|
{
|
|
|
|
return [[self settingForKey:kRCTDevSettingShakeToShowDevMenu] boolValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(setIsDebuggingRemotely:(BOOL)enabled)
|
|
|
|
{
|
|
|
|
[self _updateSettingWithValue:@(enabled) forKey:kRCTDevSettingIsDebuggingRemotely];
|
|
|
|
[self _remoteDebugSettingDidChange];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isDebuggingRemotely
|
|
|
|
{
|
|
|
|
return [[self settingForKey:kRCTDevSettingIsDebuggingRemotely] boolValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_remoteDebugSettingDidChange
|
|
|
|
{
|
|
|
|
// This value is passed as a command-line argument, so fall back to reading from NSUserDefaults directly
|
|
|
|
NSString *executorOverride = [[NSUserDefaults standardUserDefaults] stringForKey:kRCTDevSettingExecutorOverrideClass];
|
2017-03-05 00:42:55 +00:00
|
|
|
Class executorOverrideClass = executorOverride ? NSClassFromString(executorOverride) : nil;
|
|
|
|
if (executorOverrideClass) {
|
|
|
|
self.executorClass = executorOverrideClass;
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
} else {
|
|
|
|
BOOL enabled = self.isRemoteDebuggingAvailable && self.isDebuggingRemotely;
|
|
|
|
self.executorClass = enabled ? objc_getClass("RCTWebSocketExecutor") : nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(setProfilingEnabled:(BOOL)enabled)
|
|
|
|
{
|
|
|
|
[self _updateSettingWithValue:@(enabled) forKey:kRCTDevSettingProfilingEnabled];
|
|
|
|
[self _profilingSettingDidChange];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isProfilingEnabled
|
|
|
|
{
|
|
|
|
return [[self settingForKey:kRCTDevSettingProfilingEnabled] boolValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_profilingSettingDidChange
|
|
|
|
{
|
|
|
|
BOOL enabled = self.isProfilingEnabled;
|
|
|
|
if (_liveReloadURL && enabled != RCTProfileIsProfiling()) {
|
|
|
|
if (enabled) {
|
|
|
|
[_bridge startProfiling];
|
|
|
|
} else {
|
|
|
|
[_bridge stopProfiling:^(NSData *logData) {
|
|
|
|
RCTProfileSendResult(self->_bridge, @"systrace", logData);
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(setLiveReloadEnabled:(BOOL)enabled)
|
|
|
|
{
|
|
|
|
[self _updateSettingWithValue:@(enabled) forKey:kRCTDevSettingLiveReloadEnabled];
|
|
|
|
[self _liveReloadSettingDidChange];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isLiveReloadEnabled
|
|
|
|
{
|
|
|
|
return [[self settingForKey:kRCTDevSettingLiveReloadEnabled] boolValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_liveReloadSettingDidChange
|
|
|
|
{
|
|
|
|
BOOL liveReloadEnabled = (self.isLiveReloadAvailable && self.isLiveReloadEnabled);
|
|
|
|
if (liveReloadEnabled) {
|
|
|
|
[self _pollForLiveReload];
|
|
|
|
} else {
|
|
|
|
[_liveReloadUpdateTask cancel];
|
|
|
|
_liveReloadUpdateTask = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(setHotLoadingEnabled:(BOOL)enabled)
|
|
|
|
{
|
2017-08-16 18:04:17 +00:00
|
|
|
if (self.isHotLoadingEnabled != enabled) {
|
|
|
|
[self _updateSettingWithValue:@(enabled) forKey:kRCTDevSettingHotLoadingEnabled];
|
|
|
|
[_bridge reload];
|
|
|
|
}
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isHotLoadingEnabled
|
|
|
|
{
|
|
|
|
return [[self settingForKey:kRCTDevSettingHotLoadingEnabled] boolValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(toggleElementInspector)
|
|
|
|
{
|
|
|
|
BOOL value = [[self settingForKey:kRCTDevSettingIsInspectorShown] boolValue];
|
|
|
|
[self _updateSettingWithValue:@(!value) forKey:kRCTDevSettingIsInspectorShown];
|
|
|
|
|
|
|
|
if (_isJSLoaded) {
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
|
|
[self.bridge.eventDispatcher sendDeviceEventWithName:@"toggleElementInspector" body:nil];
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)toggleJSCSamplingProfiler
|
|
|
|
{
|
2017-11-21 02:12:13 +00:00
|
|
|
JSGlobalContextRef globalContext = _bridge.jsContextRef;
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
// JSPokeSamplingProfiler() toggles the profiling process
|
|
|
|
JSValueRef jsResult = JSC_JSPokeSamplingProfiler(globalContext);
|
|
|
|
|
|
|
|
if (JSC_JSValueGetType(globalContext, jsResult) != kJSTypeNull) {
|
2017-11-21 02:12:13 +00:00
|
|
|
JSContext *context = [JSC_JSContext(globalContext) contextWithJSGlobalContextRef:globalContext];
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
NSString *results = [[JSC_JSValue(globalContext) valueWithJSValueRef:jsResult inContext:context] toObject];
|
2017-04-18 20:15:25 +00:00
|
|
|
RCTJSCSamplingProfiler *profilerModule = [_bridge moduleForClass:[RCTJSCSamplingProfiler class]];
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
[profilerModule operationCompletedWithResults:results];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isElementInspectorShown
|
|
|
|
{
|
|
|
|
return [[self settingForKey:kRCTDevSettingIsInspectorShown] boolValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setIsPerfMonitorShown:(BOOL)isPerfMonitorShown
|
|
|
|
{
|
|
|
|
[self _updateSettingWithValue:@(isPerfMonitorShown) forKey:kRCTDevSettingIsPerfMonitorShown];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isPerfMonitorShown
|
|
|
|
{
|
|
|
|
return [[self settingForKey:kRCTDevSettingIsPerfMonitorShown] boolValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setStartSamplingProfilerOnLaunch:(BOOL)startSamplingProfilerOnLaunch
|
|
|
|
{
|
|
|
|
[self _updateSettingWithValue:@(startSamplingProfilerOnLaunch) forKey:kRCTDevSettingStartSamplingProfilerOnLaunch];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)startSamplingProfilerOnLaunch
|
|
|
|
{
|
|
|
|
return [[self settingForKey:kRCTDevSettingStartSamplingProfilerOnLaunch] boolValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setExecutorClass:(Class)executorClass
|
|
|
|
{
|
|
|
|
_executorClass = executorClass;
|
|
|
|
if (_bridge.executorClass != executorClass) {
|
|
|
|
|
|
|
|
// TODO (6929129): we can remove this special case test once we have better
|
|
|
|
// support for custom executors in the dev menu. But right now this is
|
|
|
|
// needed to prevent overriding a custom executor with the default if a
|
|
|
|
// custom executor has been set directly on the bridge
|
|
|
|
if (executorClass == Nil &&
|
|
|
|
_bridge.executorClass != objc_lookUpClass("RCTWebSocketExecutor")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_bridge.executorClass = executorClass;
|
|
|
|
[_bridge reload];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-21 02:12:13 +00:00
|
|
|
#if RCT_DEV
|
2017-05-05 15:32:15 +00:00
|
|
|
|
|
|
|
- (void)addHandler:(id<RCTPackagerClientMethod>)handler forPackagerMethod:(NSString *)name
|
|
|
|
{
|
2017-11-21 02:12:13 +00:00
|
|
|
#if ENABLE_PACKAGER_CONNECTION
|
|
|
|
[[RCTPackagerConnection sharedPackagerConnection] addHandler:handler forMethod:name];
|
|
|
|
#endif
|
2017-05-05 15:32:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2017-04-20 15:20:03 +00:00
|
|
|
#pragma mark - Internal
|
|
|
|
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
/**
|
|
|
|
* Query the data source for all possible settings and make sure we're doing the right
|
|
|
|
* thing for the state of each setting.
|
|
|
|
*/
|
|
|
|
- (void)_synchronizeAllSettings
|
|
|
|
{
|
|
|
|
[self _liveReloadSettingDidChange];
|
|
|
|
[self _remoteDebugSettingDidChange];
|
|
|
|
[self _profilingSettingDidChange];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)_pollForLiveReload
|
|
|
|
{
|
|
|
|
if (!_isJSLoaded || ![[self settingForKey:kRCTDevSettingLiveReloadEnabled] boolValue] || !_liveReloadURL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_liveReloadUpdateTask) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
__weak RCTDevSettings *weakSelf = self;
|
|
|
|
_liveReloadUpdateTask = [[NSURLSession sharedSession] dataTaskWithURL:_liveReloadURL completionHandler:
|
|
|
|
^(__unused NSData *data, NSURLResponse *response, NSError *error) {
|
|
|
|
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
__strong RCTDevSettings *strongSelf = weakSelf;
|
|
|
|
if (strongSelf && [[strongSelf settingForKey:kRCTDevSettingLiveReloadEnabled] boolValue]) {
|
|
|
|
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
|
|
|
|
if (!error && HTTPResponse.statusCode == 205) {
|
|
|
|
[strongSelf reload];
|
|
|
|
} else {
|
|
|
|
if (error.code != NSURLErrorCancelled) {
|
|
|
|
strongSelf->_liveReloadUpdateTask = nil;
|
|
|
|
[strongSelf _pollForLiveReload];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
[_liveReloadUpdateTask resume];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)jsLoaded:(NSNotification *)notification
|
|
|
|
{
|
|
|
|
if (notification.userInfo[@"bridge"] != _bridge) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_isJSLoaded = YES;
|
|
|
|
|
|
|
|
// Check if live reloading is available
|
|
|
|
NSURL *scriptURL = _bridge.bundleURL;
|
|
|
|
if (![scriptURL isFileURL]) {
|
|
|
|
// Live reloading is disabled when running from bundled JS file
|
|
|
|
_liveReloadURL = [[NSURL alloc] initWithString:@"/onchange" relativeToURL:scriptURL];
|
|
|
|
} else {
|
|
|
|
_liveReloadURL = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
// update state again after the bridge has finished loading
|
|
|
|
[self _synchronizeAllSettings];
|
2017-03-20 19:40:16 +00:00
|
|
|
|
|
|
|
// Inspector can only be shown after JS has loaded
|
|
|
|
if ([self isElementInspectorShown]) {
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
|
|
[self.bridge.eventDispatcher sendDeviceEventWithName:@"toggleElementInspector" body:nil];
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
}
|
Add RCTDevSettings module
Summary:
This decouples non-UI logic from RCTDevMenu into a new module RCTDevSettings.
**Motivation**: This allows developers to change dev settings without depending on the built-in dev menu, e.g. if they want to introduce their own UI, or have other devtools logic that doesn't depend on an action sheet.
It also introduces the RCTDevSettingsDataSource protocol for storing dev tools preferences. This could allow a developer to implement alternative behaviors, e.g. loading the settings from some other config, changing settings based on the user, deciding not to persist some settings, or something else.
The included data source implementation, RCTDevSettingsUserDefaultsDataSource, uses NSUserDefaults and is backwards compatible with the older implementation, so **no workflows or dependent code will break, and old saved settings will persist.**
The RCTDevMenu interface has not changed and is therefore also backwards-compatible, though
some methods are now deprecated.
In order to ensure that RCTDevSettings
Closes https://github.com/facebook/react-native/pull/11613
Reviewed By: mmmulani
Differential Revision: D4571773
Pulled By: javache
fbshipit-source-id: 25555d0a6eaa81f694343e079ed02439e5845fbc
2017-02-24 14:50:29 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
#else // #if RCT_DEV
|
|
|
|
|
|
|
|
@implementation RCTDevSettings
|
|
|
|
|
|
|
|
- (instancetype)initWithDataSource:(id<RCTDevSettingsDataSource>)dataSource { return [super init]; }
|
|
|
|
- (BOOL)isHotLoadingAvailable { return NO; }
|
|
|
|
- (BOOL)isLiveReloadAvailable { return NO; }
|
|
|
|
- (BOOL)isRemoteDebuggingAvailable { return NO; }
|
|
|
|
- (id)settingForKey:(NSString *)key { return nil; }
|
|
|
|
- (void)reload {}
|
|
|
|
- (void)toggleElementInspector {}
|
|
|
|
- (void)toggleJSCSamplingProfiler {}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
@implementation RCTBridge (RCTDevSettings)
|
|
|
|
|
|
|
|
- (RCTDevSettings *)devSettings
|
|
|
|
{
|
|
|
|
#if RCT_DEV
|
|
|
|
return [self moduleForClass:[RCTDevSettings class]];
|
|
|
|
#else
|
|
|
|
return nil;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|