diff --git a/Examples/UIExplorer/UIExplorer/AppDelegate.m b/Examples/UIExplorer/UIExplorer/AppDelegate.m index b0d19a59c170ac..11f5adf3765588 100644 --- a/Examples/UIExplorer/UIExplorer/AppDelegate.m +++ b/Examples/UIExplorer/UIExplorer/AppDelegate.m @@ -18,6 +18,7 @@ #import "RCTJavaScriptLoader.h" #import "RCTLinkingManager.h" #import "RCTRootView.h" +#import "RCTUtils.h" @interface AppDelegate() @@ -46,36 +47,10 @@ - (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge { NSURL *sourceURL; - /** - * Loading JavaScript code - uncomment the one you want. - * - * OPTION 1 - * Load from development server. Start the server from the repository root: - * - * $ npm start - * - * To run on device, change `localhost` to the IP address of your computer - * (you can get this by typing `ifconfig` into the terminal and selecting the - * `inet` value under `en0:`) and make sure your computer and iOS device are - * on the same Wi-Fi network. - */ - - sourceURL = [NSURL URLWithString:@"http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.bundle?platform=ios&dev=true"]; - - /** - * OPTION 2 - * Load from pre-bundled file on disk. To re-generate the static bundle, `cd` - * to your Xcode project folder and run - * - * $ curl 'http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.bundle?platform=ios' -o main.jsbundle - * - * then add the `main.jsbundle` file to your project and uncomment this line: - */ - - // sourceURL = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; - #if RUNNING_ON_CI sourceURL = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; + #else + sourceURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@:8081/Examples/UIExplorer/UIExplorerApp.ios.bundle?platform=ios&dev=true", RCTGuessPackagerIP()]]; #endif return sourceURL; diff --git a/Libraries/WebSocket/RCTWebSocketExecutor.m b/Libraries/WebSocket/RCTWebSocketExecutor.m index de26e8a91857f2..586096b905dd95 100644 --- a/Libraries/WebSocket/RCTWebSocketExecutor.m +++ b/Libraries/WebSocket/RCTWebSocketExecutor.m @@ -17,6 +17,7 @@ #import "RCTLog.h" #import "RCTUtils.h" #import "RCTSRWebSocket.h" +#import "RCTBridge.h" typedef void (^RCTWSMessageCallback)(NSError *error, NSDictionary *reply); @@ -36,6 +37,8 @@ @implementation RCTWebSocketExecutor RCT_EXPORT_MODULE() +@synthesize bridge; + - (instancetype)initWithURL:(NSURL *)URL { RCTAssertParam(URL); @@ -49,9 +52,25 @@ - (instancetype)initWithURL:(NSURL *)URL - (void)setUp { if (!_url) { + NSString *host = @"localhost"; + NSInteger port = 8081; + + NSURL *bundleURL = self.bridge.bundleURL; + if ([bundleURL.scheme hasPrefix:@"http"]) { + host = bundleURL.host; + port = [bundleURL.port integerValue]; + } + + // Some external tools can launch React Native apps with -websocket-executor-port 9091 flag + // to force websocket debugger use different port. In the future we want to replace this + // ability by always proxying debugger connections via packager. NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults]; - NSInteger port = [standardDefaults integerForKey:@"websocket-executor-port"] ?: 8081; - NSString *URLString = [NSString stringWithFormat:@"http://localhost:%zd/debugger-proxy?role=client", port]; + NSInteger forcePort = [standardDefaults integerForKey:@"websocket-executor-port"]; + if (forcePort > 0) { + port = forcePort; + } + + NSString *URLString = [NSString stringWithFormat:@"http://%@:%zd/debugger-proxy?role=client", host, port]; _url = [RCTConvert NSURL:URLString]; } diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h index ea319814588cf2..00b0bbe906a175 100644 --- a/React/Base/RCTUtils.h +++ b/React/Base/RCTUtils.h @@ -122,4 +122,7 @@ RCT_EXTERN NSString *RCTUIKitLocalizedString(NSString *string); RCT_EXTERN NSString *__nullable RCTGetURLQueryParam(NSURL *__nullable URL, NSString *param); RCT_EXTERN NSURL *__nullable RCTURLByReplacingQueryParam(NSURL *__nullable URL, NSString *param, NSString *__nullable value); +// Development mode +RCT_EXTERN NSString *RCTGuessPackagerIP(); + NS_ASSUME_NONNULL_END diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index c693ea1a702ef2..13e73779952f14 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -773,3 +773,17 @@ static void RCTGetRGBAColorComponents(CGColorRef color, CGFloat rgba[4]) components.percentEncodedQuery = [queryItems componentsJoinedByString:@"&"]; return components.URL; } + +NSString *RCTGuessPackagerIP() +{ + // For development builds there is a script that saves current development + // machine's IP address + // See packager/react-native-xcode.sh + NSString *ipAddressFile = [[NSBundle mainBundle] pathForResource:@"packager-ip" ofType:@"txt"] ; + NSString *ip = [[NSString stringWithContentsOfFile:ipAddressFile encoding:NSUTF8StringEncoding error:nil] + stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\n"]]; + if (!ip) { + return @"127.0.0.1"; + } + return ip; +} diff --git a/local-cli/generator-ios/templates/app/AppDelegate.m b/local-cli/generator-ios/templates/app/AppDelegate.m index 909092b9cc757a..cd9e4faebe9206 100644 --- a/local-cli/generator-ios/templates/app/AppDelegate.m +++ b/local-cli/generator-ios/templates/app/AppDelegate.m @@ -10,6 +10,7 @@ #import "AppDelegate.h" #import "RCTRootView.h" +#import "RCTUtils.h" @implementation AppDelegate @@ -18,30 +19,34 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( NSURL *jsCodeLocation; /** - * Loading JavaScript code - uncomment the one you want. + * The JavaScript code can be loaded from development server (packager) or + * a file bundled within the app * * OPTION 1 * Load from development server. Start the server from the repository root: * * $ npm start * - * To run on device, change `localhost` to the IP address of your computer - * (you can get this by typing `ifconfig` into the terminal and selecting the - * `inet` value under `en0:`) and make sure your computer and iOS device are - * on the same Wi-Fi network. - */ - - jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; - - /** + * When running on device make sure your computer and iOS device are on + * the same Wi-Fi network. + * * OPTION 2 * Load from pre-bundled file on disk. The static bundle is automatically * generated by the "Bundle React Native code and images" build step when * running the project on an actual device or running the project on the * simulator in the "Release" build configuration. + * + * + * The code below is generated to streamline the most common development flow: + * loading from the packager in development mode and using pre-packaged JS + * file in production. */ -// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; +#ifdef DEBUG + jsCodeLocation = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@:8081/index.ios.bundle?platform=ios&dev=true", RCTGuessPackagerIP()]]; +#else + jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; +#endif RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"<%= name %>" diff --git a/packager/react-native-xcode.sh b/packager/react-native-xcode.sh index 9e6ffbe438c997..b627af2a9b6e5e 100755 --- a/packager/react-native-xcode.sh +++ b/packager/react-native-xcode.sh @@ -10,15 +10,21 @@ # This script is supposed to be invoked as part of Xcode build process # and relies on environment variables (including PWD) set by Xcode +DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH + +if [[ "$CONFIGURATION" = "Debug" && "$PLATFORM_NAME" != "iphonesimulator" ]]; then + ipconfig getifaddr en0 > "$DEST/packager-ip.txt" +fi + case "$CONFIGURATION" in Debug) # Speed up build times by skipping the creation of the offline package for debug # builds on the simulator since the packager is supposed to be running anyways. - if [[ "$PLATFORM_NAME" = "iphonesimulator" ]]; then - echo "Skipping bundling for Simulator platform" - exit 0; + if [[ "$PLATFORM_NAME" = "iphonesimulator" ]]; then + echo "Skipping bundling for Simulator platform" + exit 0; fi - + DEV=true ;; "") @@ -66,7 +72,6 @@ type $NODE_BINARY >/dev/null 2>&1 || nodejs_not_found # Print commands before executing them (useful for troubleshooting) set -x -DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH $NODE_BINARY "$REACT_NATIVE_DIR/local-cli/cli.js" bundle \ --entry-file index.ios.js \