From fd96e2cb2c4faf90630a4a9a3a79cc3d0eaf2112 Mon Sep 17 00:00:00 2001 From: Luis Rivera Date: Wed, 20 Feb 2019 21:50:13 -0800 Subject: [PATCH] Feature: dev menu option to change packager location during runtime (#21970) Summary: Add an option to dev menu to change packager location on the fly on iOS (similar to Dev Settings in Android) Pull Request resolved: https://github.com/facebook/react-native/pull/21970 Differential Revision: D14162776 Pulled By: cpojer fbshipit-source-id: 3cca4f4fbd8c599bd5342ba1ae64905a03270d48 --- React/Base/RCTBundleURLProvider.m | 13 ++++--- React/DevSupport/RCTDevMenu.m | 56 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/React/Base/RCTBundleURLProvider.m b/React/Base/RCTBundleURLProvider.m index 21daefe307e472..e7557674dfd34f 100644 --- a/React/Base/RCTBundleURLProvider.m +++ b/React/Base/RCTBundleURLProvider.m @@ -58,17 +58,22 @@ - (void)resetToDefaults [self settingsUpdated]; } -static NSURL *serverRootWithHost(NSString *host) +static NSURL *serverRootWithHostPort(NSString *hostPort) { + if([hostPort rangeOfString:@":"].location != NSNotFound){ + return [NSURL URLWithString: + [NSString stringWithFormat:@"http://%@/", + hostPort]]; + } return [NSURL URLWithString: [NSString stringWithFormat:@"http://%@:%lu/", - host, (unsigned long)kRCTBundleURLProviderDefaultPort]]; + hostPort, (unsigned long)kRCTBundleURLProviderDefaultPort]]; } #if RCT_DEV - (BOOL)isPackagerRunning:(NSString *)host { - NSURL *url = [serverRootWithHost(host) URLByAppendingPathComponent:@"status"]; + NSURL *url = [serverRootWithHostPort(host) URLByAppendingPathComponent:@"status"]; NSURLSession *session = [NSURLSession sharedSession]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; @@ -181,7 +186,7 @@ + (NSURL *)resourceURLForResourcePath:(NSString *)path packagerHost:(NSString *)packagerHost query:(NSString *)query { - NSURLComponents *components = [NSURLComponents componentsWithURL:serverRootWithHost(packagerHost) resolvingAgainstBaseURL:NO]; + NSURLComponents *components = [NSURLComponents componentsWithURL:serverRootWithHostPort(packagerHost) resolvingAgainstBaseURL:NO]; components.path = path; if (query != nil) { components.query = query; diff --git a/React/DevSupport/RCTDevMenu.m b/React/DevSupport/RCTDevMenu.m index 95a090c48b0620..eff6040f8d1eb0 100644 --- a/React/DevSupport/RCTDevMenu.m +++ b/React/DevSupport/RCTDevMenu.m @@ -12,6 +12,8 @@ #import "RCTKeyCommands.h" #import "RCTLog.h" #import "RCTUtils.h" +#import "RCTDefines.h" +#import #if RCT_DEV @@ -189,6 +191,12 @@ - (void)addItem:(RCTDevMenuItem *)item [_extraMenuItems addObject:item]; } +- (void)setDefaultJSBundle { + [[RCTBundleURLProvider sharedSettings] resetToDefaults]; + self->_bridge.bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForFallbackResource:nil fallbackExtension:nil]; + [self->_bridge reload]; +} + - (NSArray *)_menuItemsToPresent { NSMutableArray *items = [NSMutableArray new]; @@ -269,6 +277,54 @@ - (void)addItem:(RCTDevMenuItem *)item }]]; } + [items addObject:[RCTDevMenuItem buttonItemWithTitleBlock:^NSString *{ + return @"Change packager location"; + } handler:^{ + UIAlertController * alertController = [UIAlertController alertControllerWithTitle: @"Change packager location" + message: @"Input packager IP, port and entrypoint" + preferredStyle:UIAlertControllerStyleAlert]; + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.placeholder = @"0.0.0.0"; + }]; + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.placeholder = @"8081"; + }]; + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { + textField.placeholder = @"index"; + }]; + [alertController addAction:[UIAlertAction actionWithTitle:@"Use bundled JS" style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction *action) { + [self setDefaultJSBundle]; + }]]; + [alertController addAction:[UIAlertAction actionWithTitle:@"Use packager location" style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction *action) { + NSArray * textfields = alertController.textFields; + UITextField * ipTextField = textfields[0]; + UITextField * portTextField = textfields[1]; + UITextField * bundleRootTextField = textfields[2]; + NSString * bundleRoot = bundleRootTextField.text; + if(bundleRoot.length==0){ + bundleRoot = @"index"; + } + if(ipTextField.text.length == 0 && portTextField.text.length == 0) { + [self setDefaultJSBundle]; + return; + } + NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; + formatter.numberStyle = NSNumberFormatterDecimalStyle; + NSNumber *portNumber = [formatter numberFromString:portTextField.text]; + if (portNumber == nil) { + portNumber = [NSNumber numberWithInt: RCT_METRO_PORT]; + } + [RCTBundleURLProvider sharedSettings].jsLocation = [NSString stringWithFormat:@"%@:%d", + ipTextField.text, portNumber.intValue]; + self->_bridge.bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:bundleRoot fallbackResource:nil]; + [self->_bridge reload]; + }]]; + [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(__unused UIAlertAction *action) { + return; + }]]; + [RCTPresentedViewController() presentViewController:alertController animated:YES completion:NULL]; + }]]; + [items addObject:[RCTDevMenuItem buttonItemWithTitleBlock:^NSString *{ return @"Toggle Inspector"; } handler:^{