diff --git a/Examples/2048/2048.xcodeproj/project.pbxproj b/Examples/2048/2048.xcodeproj/project.pbxproj
index 48ebefe41fd54f..fd43726638af49 100644
--- a/Examples/2048/2048.xcodeproj/project.pbxproj
+++ b/Examples/2048/2048.xcodeproj/project.pbxproj
@@ -140,6 +140,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "2048" */;
buildPhases = (
+ 4CED848A1B37581600715E21 /* ShellScript */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
@@ -230,6 +231,22 @@
};
/* End PBXResourcesBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 4CED848A1B37581600715E21 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "if [ -d \"$SRCROOT/../../packager\" ]\nthen\n PACKAGER_ROOT=$SRCROOT/../../packager\nelse\n PACKAGER_ROOT=$SRCROOT/node_modules/react-native/packager\nfi\n\n$PACKAGER_ROOT/launchPackager.command ${INFOPLIST_FILE}\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
13B07F871A680F5B00A75B9A /* Sources */ = {
isa = PBXSourcesBuildPhase;
diff --git a/Examples/2048/2048/AppDelegate.m b/Examples/2048/2048/AppDelegate.m
index b4b1769ff28d0d..817d1daf39661b 100644
--- a/Examples/2048/2048/AppDelegate.m
+++ b/Examples/2048/2048/AppDelegate.m
@@ -15,6 +15,7 @@
#import "AppDelegate.h"
#import "RCTRootView.h"
+#import "RCTUtils.h"
@implementation AppDelegate
@@ -36,7 +37,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
* on the same Wi-Fi network.
*/
- jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/2048/Game2048.bundle?platform=ios&dev=true"];
+ jsCodeLocation = RCTPackagerURL(@"/Examples/2048/Game2048.bundle?platform=ios&dev=true");
/**
* OPTION 2
diff --git a/Examples/2048/2048/Info.plist b/Examples/2048/2048/Info.plist
index 6105445463d64b..0aedb782723a44 100644
--- a/Examples/2048/2048/Info.plist
+++ b/Examples/2048/2048/Info.plist
@@ -39,5 +39,12 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+ RCTPackager
+
+ url
+ http://localhost
+ port
+ 8088
+
diff --git a/Examples/Movies/Movies.xcodeproj/project.pbxproj b/Examples/Movies/Movies.xcodeproj/project.pbxproj
index f3937e4285ad60..717987870a6a1f 100644
--- a/Examples/Movies/Movies.xcodeproj/project.pbxproj
+++ b/Examples/Movies/Movies.xcodeproj/project.pbxproj
@@ -197,6 +197,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Movies" */;
buildPhases = (
+ 4CED84A71B37590B00715E21 /* ShellScript */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
@@ -320,6 +321,22 @@
};
/* End PBXResourcesBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 4CED84A71B37590B00715E21 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "if [ -d \"$SRCROOT/../../packager\" ]\nthen\n PACKAGER_ROOT=$SRCROOT/../../packager\nelse\n PACKAGER_ROOT=$SRCROOT/node_modules/react-native/packager\nfi\n\n$PACKAGER_ROOT/launchPackager.command ${INFOPLIST_FILE}\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
13B07F871A680F5B00A75B9A /* Sources */ = {
isa = PBXSourcesBuildPhase;
diff --git a/Examples/Movies/Movies/AppDelegate.m b/Examples/Movies/Movies/AppDelegate.m
index 4d322023f03032..8b0cbb6d598344 100644
--- a/Examples/Movies/Movies/AppDelegate.m
+++ b/Examples/Movies/Movies/AppDelegate.m
@@ -16,6 +16,7 @@
#import "RCTLinkingManager.h"
#import "RCTRootView.h"
+#import "RCTUtils.h"
@implementation AppDelegate
@@ -37,7 +38,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
* on the same Wi-Fi network.
*/
- jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/Movies/MoviesApp.ios.bundle?platform=ios&dev=true"];
+ jsCodeLocation = RCTPackagerURL(@"/Examples/Movies/MoviesApp.ios.bundle?platform=ios&dev=true");
/**
* OPTION 2
diff --git a/Examples/Movies/Movies/Info.plist b/Examples/Movies/Movies/Info.plist
index 4ecf97f70446d6..e2f4239a5ffc59 100644
--- a/Examples/Movies/Movies/Info.plist
+++ b/Examples/Movies/Movies/Info.plist
@@ -52,5 +52,16 @@
UIViewControllerBasedStatusBarAppearance
+
+ NSAllowsArbitraryLoads
+
+
+ RCTPackager
+
+ url
+ http://localhost
+ port
+ 8089
+
diff --git a/Examples/SampleApp/iOS/SampleApp.xcodeproj/project.pbxproj b/Examples/SampleApp/iOS/SampleApp.xcodeproj/project.pbxproj
index 7123b2d3b2cdac..b5a5baec46429a 100644
--- a/Examples/SampleApp/iOS/SampleApp.xcodeproj/project.pbxproj
+++ b/Examples/SampleApp/iOS/SampleApp.xcodeproj/project.pbxproj
@@ -331,6 +331,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "SampleApp" */;
buildPhases = (
+ 4CED847C1B3756CA00715E21 /* ShellScript */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
@@ -513,6 +514,22 @@
};
/* End PBXResourcesBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 4CED847C1B3756CA00715E21 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "if [ -d \"$SRCROOT/../../packager\" ]\nthen\n PACKAGER_ROOT=$SRCROOT/../../packager\nelse\n PACKAGER_ROOT=$SRCROOT/node_modules/react-native/packager\nfi\n\n$PACKAGER_ROOT/launchPackager.command ${INFOPLIST_FILE}\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
00E356EA1AD99517003FC87E /* Sources */ = {
isa = PBXSourcesBuildPhase;
diff --git a/Examples/SampleApp/iOS/SampleApp/Info.plist b/Examples/SampleApp/iOS/SampleApp/Info.plist
index cddf0766c98062..2924782bd13c15 100644
--- a/Examples/SampleApp/iOS/SampleApp/Info.plist
+++ b/Examples/SampleApp/iOS/SampleApp/Info.plist
@@ -38,11 +38,17 @@
NSLocationWhenInUseUsageDescription
- NSAppTransportSecurity
-
-
- NSAllowsArbitraryLoads
-
-
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
+ RCTPackager
+
+ url
+ http://localhost
+ port
+ 8087
+
diff --git a/Examples/TicTacToe/TicTacToe.xcodeproj/project.pbxproj b/Examples/TicTacToe/TicTacToe.xcodeproj/project.pbxproj
index ec0802a837de54..9b2129c8d7f6c5 100644
--- a/Examples/TicTacToe/TicTacToe.xcodeproj/project.pbxproj
+++ b/Examples/TicTacToe/TicTacToe.xcodeproj/project.pbxproj
@@ -178,6 +178,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "TicTacToe" */;
buildPhases = (
+ 4CED84BE1B3759D900715E21 /* ShellScript */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
@@ -290,6 +291,22 @@
};
/* End PBXResourcesBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 4CED84BE1B3759D900715E21 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "if [ -d \"$SRCROOT/../../packager\" ]\nthen\n PACKAGER_ROOT=$SRCROOT/../../packager\nelse\n PACKAGER_ROOT=$SRCROOT/node_modules/react-native/packager\nfi\n\n$PACKAGER_ROOT/launchPackager.command ${INFOPLIST_FILE}\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
13B07F871A680F5B00A75B9A /* Sources */ = {
isa = PBXSourcesBuildPhase;
diff --git a/Examples/TicTacToe/TicTacToe/AppDelegate.m b/Examples/TicTacToe/TicTacToe/AppDelegate.m
index f0199b6dd64650..5fb4867a86a7f3 100644
--- a/Examples/TicTacToe/TicTacToe/AppDelegate.m
+++ b/Examples/TicTacToe/TicTacToe/AppDelegate.m
@@ -15,6 +15,7 @@
#import "AppDelegate.h"
#import "RCTRootView.h"
+#import "RCTUtils.h"
@implementation AppDelegate
@@ -36,8 +37,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
* on the same Wi-Fi network.
*/
- jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/TicTacToe/TicTacToeApp.bundle?platform=ios&dev=true"];
-
+ jsCodeLocation = RCTPackagerURL(@"/Examples/TicTacToe/TicTacToeApp.bundle?platform=ios&dev=true");
+
/**
* OPTION 2
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
diff --git a/Examples/TicTacToe/TicTacToe/Info.plist b/Examples/TicTacToe/TicTacToe/Info.plist
index 25742279c9dce4..857be1cea459b4 100644
--- a/Examples/TicTacToe/TicTacToe/Info.plist
+++ b/Examples/TicTacToe/TicTacToe/Info.plist
@@ -37,10 +37,16 @@
UIViewControllerBasedStatusBarAppearance
NSAppTransportSecurity
-
-
- NSAllowsArbitraryLoads
-
-
+
+ NSAllowsArbitraryLoads
+
+
+ RCTPackager
+
+ url
+ http://localhost
+ port
+ 8090
+
diff --git a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
index a259da744d332d..5c5cf505df9881 100644
--- a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
+++ b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
@@ -35,7 +35,6 @@
1497CFB11B21F5E400C1F8F2 /* RCTEventDispatcherTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA91B21F5E400C1F8F2 /* RCTEventDispatcherTests.m */; };
1497CFB21B21F5E400C1F8F2 /* RCTSparseArrayTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFAA1B21F5E400C1F8F2 /* RCTSparseArrayTests.m */; };
1497CFB31B21F5E400C1F8F2 /* RCTUIManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFAB1B21F5E400C1F8F2 /* RCTUIManagerTests.m */; };
- 14AADF051AC3DBB1002390C9 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14AADF041AC3DB95002390C9 /* libReact.a */; };
14B6DA821B276C5900BF4DD1 /* libRCTTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58005BEE1ABA80530062E044 /* libRCTTest.a */; };
14D6D7111B220EB3001FB087 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14D6D7101B220EB3001FB087 /* libOCMock.a */; };
14D6D71E1B2222EF001FB087 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */; };
@@ -52,7 +51,7 @@
14D6D7291B2222EF001FB087 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14AADF041AC3DB95002390C9 /* libReact.a */; };
14DC67F41AB71881001358AB /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DC67F11AB71876001358AB /* libRCTPushNotification.a */; };
3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 357859011B28D2C500341EDB /* libRCTLinking.a */; };
- 3DB99D0C1BA0340600302749 /* UIExplorerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB99D0B1BA0340600302749 /* UIExplorerIntegrationTests.m */; };
+ 4CED845A1B3754F400715E21 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14AADF041AC3DB95002390C9 /* libReact.a */; };
834C36EC1AF8DED70019C93C /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 834C36D21AF8DA610019C93C /* libRCTSettings.a */; };
83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; };
8385CEF51B873B5C00C6273E /* RCTImageLoaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8385CEF41B873B5C00C6273E /* RCTImageLoaderTests.m */; };
@@ -260,7 +259,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 14AADF051AC3DBB1002390C9 /* libReact.a in Frameworks */,
+ 4CED845A1B3754F400715E21 /* libReact.a in Frameworks */,
147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */,
134454601AAFCABD003F0779 /* libRCTAdSupport.a in Frameworks */,
138DEE241B9EDFB6007F4EA5 /* libRCTCameraRoll.a in Frameworks */,
@@ -557,6 +556,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 004D28AD1AAF61C70097A701 /* Build configuration list for PBXNativeTarget "UIExplorerUnitTests" */;
buildPhases = (
+ 4CED84D91B3760EE00715E21 /* ShellScript */,
004D289A1AAF61C70097A701 /* Sources */,
004D289B1AAF61C70097A701 /* Frameworks */,
004D289C1AAF61C70097A701 /* Resources */,
@@ -574,6 +574,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "UIExplorer" */;
buildPhases = (
+ 4CC373051B23ADA4004C3480 /* ShellScript */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
@@ -828,6 +829,35 @@
};
/* End PBXResourcesBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 4CC373051B23ADA4004C3480 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "if [ -d \"$SRCROOT/../../packager\" ]\nthen\n PACKAGER_ROOT=$SRCROOT/../../packager\nelse\n PACKAGER_ROOT=$SRCROOT/node_modules/react-native/packager\nfi\n\n$PACKAGER_ROOT/launchPackager.command ${INFOPLIST_FILE}\n";
+ };
+ 4CED84D91B3760EE00715E21 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "if [ -d \"$SRCROOT/../../packager\" ]\nthen\n PACKAGER_ROOT=$SRCROOT/../../packager\nelse\n PACKAGER_ROOT=$SRCROOT/node_modules/react-native/packager\nfi\n\n$PACKAGER_ROOT/launchPackager.command ${INFOPLIST_FILE}\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
004D289A1AAF61C70097A701 /* Sources */ = {
isa = PBXSourcesBuildPhase;
diff --git a/Examples/UIExplorer/UIExplorer/AppDelegate.m b/Examples/UIExplorer/UIExplorer/AppDelegate.m
index 1d0d0079cf5691..cab4dd63840ec4 100644
--- a/Examples/UIExplorer/UIExplorer/AppDelegate.m
+++ b/Examples/UIExplorer/UIExplorer/AppDelegate.m
@@ -17,6 +17,7 @@
#import "RCTBridge.h"
#import "RCTJavaScriptLoader.h"
#import "RCTRootView.h"
+#import "RCTUtils.h"
@interface AppDelegate()
@@ -59,8 +60,8 @@ - (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge
* on the same Wi-Fi network.
*/
- sourceURL = [NSURL URLWithString:@"http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.bundle?platform=ios&dev=true"];
-
+ sourceURL = RCTPackagerURL(@"/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`
diff --git a/Examples/UIExplorer/UIExplorer/Info.plist b/Examples/UIExplorer/UIExplorer/Info.plist
index 9e91b1cef8cc6b..094ed9e8c4e685 100644
--- a/Examples/UIExplorer/UIExplorer/Info.plist
+++ b/Examples/UIExplorer/UIExplorer/Info.plist
@@ -22,8 +22,6 @@
1
LSRequiresIPhoneOS
- NSLocationWhenInUseUsageDescription
- You need to add NSLocationWhenInUseUsageDescription key in Info.plist to enable geolocation, otherwise it is going to *fail silently*!
UILaunchStoryboardName
LaunchScreen
UIRequiredDeviceCapabilities
@@ -36,13 +34,21 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+ NSLocationWhenInUseUsageDescription
+ You need to add NSLocationWhenInUseUsageDescription key in Info.plist to enable geolocation, otherwise it is going to *fail silently*!
UIViewControllerBasedStatusBarAppearance
+ RCTPackager
+
+ url
+ http://localhost
+ port
+ 8081
+
NSAppTransportSecurity
-
-
- NSAllowsArbitraryLoads
-
-
+
+ NSAllowsArbitraryLoads
+
+
diff --git a/Libraries/RCTTest/RCTTestRunner.m b/Libraries/RCTTest/RCTTestRunner.m
index 41316360ba1271..bd6d85cb634bef 100644
--- a/Libraries/RCTTest/RCTTestRunner.m
+++ b/Libraries/RCTTest/RCTTestRunner.m
@@ -44,7 +44,7 @@ - (instancetype)initWithApp:(NSString *)app
_scriptURL = [[NSBundle bundleForClass:[RCTBridge class]] URLForResource:@"main" withExtension:@"jsbundle"];
RCTAssert(_scriptURL != nil, @"Could not locate main.jsBundle");
#else
- _scriptURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:8081/%@.bundle?platform=ios&dev=true", app]];
+ _scriptURL = RCTPackagerURL( [NSString stringWithFormat:@"/%@.bundle?platform=ios&dev=true", app] );
#endif
}
return self;
diff --git a/Libraries/WebSocket/RCTWebSocketExecutor.m b/Libraries/WebSocket/RCTWebSocketExecutor.m
index 815ab56d1c280a..3c50a7e7b40674 100644
--- a/Libraries/WebSocket/RCTWebSocketExecutor.m
+++ b/Libraries/WebSocket/RCTWebSocketExecutor.m
@@ -39,7 +39,7 @@ @implementation RCTWebSocketExecutor
- (instancetype)init
{
- return [self initWithURL:[RCTConvert NSURL:@"http://localhost:8081/debugger-proxy"]];
+ return [self initWithURL:RCTPackagerURL(@"/debugger-proxy")];
}
- (instancetype)initWithURL:(NSURL *)URL
diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h
index 65eb99f8c2ed58..ad583bf0bab82f 100644
--- a/React/Base/RCTUtils.h
+++ b/React/Base/RCTUtils.h
@@ -66,3 +66,6 @@ RCT_EXTERN NSURL *RCTDataURL(NSString *mimeType, NSData *data);
// Gzip functionality - compression level in range 0 - 1 (-1 for default)
RCT_EXTERN NSData *RCTGzipData(NSData *data, float level);
+
+// Create NSURL for jsCodeLocation in AppDelegate:application
+RCT_EXTERN NSURL *RCTPackagerURL(NSString *appendString);
diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m
index 2fba55f00486bf..baa49c68347224 100644
--- a/React/Base/RCTUtils.m
+++ b/React/Base/RCTUtils.m
@@ -422,3 +422,21 @@ BOOL RCTIsGzippedData(NSData *data)
return output;
}
+
+NSURL *RCTPackagerURL(NSString *appendString)
+{
+ NSMutableString *url;
+ NSDictionary *dict = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"RCTPackager"];
+ if (dict) {
+ NSString *port = [NSString stringWithFormat:@"%@", [dict objectForKey:@"port"]];
+ url = [NSMutableString stringWithString:dict[@"url"]];
+ [url appendString:@":"];
+ [url appendString:port];
+ } else {
+ url = [NSMutableString stringWithString:@"http://localhost:8081"];
+ }
+ // i.e. @"/Examples/UIExplorer/UIExplorerApp.ios.includeRequire.runModule.bundle?dev=true"
+ [url appendString:appendString];
+
+ return [NSURL URLWithString:url];
+}
diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj
index 276e3943d04252..50028092a36782 100644
--- a/React/React.xcodeproj/project.pbxproj
+++ b/React/React.xcodeproj/project.pbxproj
@@ -517,7 +517,6 @@
isa = PBXNativeTarget;
buildConfigurationList = 83CBBA3F1A601D0F00E9B192 /* Build configuration list for PBXNativeTarget "React" */;
buildPhases = (
- 006B79A01A781F38006873D1 /* ShellScript */,
83CBBA2A1A601D0E00E9B192 /* Sources */,
83CBBA2B1A601D0E00E9B192 /* Frameworks */,
83CBBA2C1A601D0E00E9B192 /* Copy Files */,
diff --git a/local-cli/generator-ios/templates/app/AppDelegate.m b/local-cli/generator-ios/templates/app/AppDelegate.m
index 3f96e60fe47ff4..8d8f9a34c8adff 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
@@ -31,7 +32,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
* on the same Wi-Fi network.
*/
- jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
+ jsCodeLocation = RCTPackagerURL(@"/index.ios.bundle?platform=ios&dev=true");
/**
* OPTION 2
diff --git a/local-cli/generator-ios/templates/app/Info.plist b/local-cli/generator-ios/templates/app/Info.plist
index cddf0766c98062..ad4feac9ead957 100644
--- a/local-cli/generator-ios/templates/app/Info.plist
+++ b/local-cli/generator-ios/templates/app/Info.plist
@@ -38,11 +38,17 @@
NSLocationWhenInUseUsageDescription
- NSAppTransportSecurity
-
-
- NSAllowsArbitraryLoads
-
-
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
+ RCTPackager
+
+ url
+ http://localhost
+ port
+ 8081
+
diff --git a/local-cli/generator-ios/templates/xcodeproj/project.pbxproj b/local-cli/generator-ios/templates/xcodeproj/project.pbxproj
index f3955bb8798754..8710627fcd80a5 100644
--- a/local-cli/generator-ios/templates/xcodeproj/project.pbxproj
+++ b/local-cli/generator-ios/templates/xcodeproj/project.pbxproj
@@ -513,6 +513,35 @@
};
/* End PBXResourcesBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 5CC373051B23ADA4004C3480 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "if [ -d \"$SRCROOT/../../packager\" ]\nthen\n PACKAGER_ROOT=$SRCROOT/../../packager\nelse\n PACKAGER_ROOT=$SRCROOT/node_modules/react-native/packager\nfi\n\n$PACKAGER_ROOT/launchPackager.command ${INFOPLIST_FILE}\n";
+ };
+ 5CED84D91B3760EE00715E21 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "if [ -d \"$SRCROOT/../../packager\" ]\nthen\n PACKAGER_ROOT=$SRCROOT/../../packager\nelse\n PACKAGER_ROOT=$SRCROOT/node_modules/react-native/packager\nfi\n\n$PACKAGER_ROOT/launchPackager.command ${INFOPLIST_FILE}\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
00E356EA1AD99517003FC87E /* Sources */ = {
isa = PBXSourcesBuildPhase;
diff --git a/packager/launchPackager.command b/packager/launchPackager.command
index 0537f7c84d8105..7319834fb45e0e 100755
--- a/packager/launchPackager.command
+++ b/packager/launchPackager.command
@@ -7,11 +7,40 @@
# 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.
-# Set terminal title
-echo -en "\033]0;React Packager\a"
-clear
+
+if [ -z "$1" ]; then
+ echo "Missing argument: \$INFOPLIST_FILE"
+ exit 0
+fi
+
+export INFOPLIST_FILE=$1
+
+# extract RCTPackager/protocol from Info.plist
+URL=$(/usr/libexec/PlistBuddy -c "Print :RCTPackager:url" "${INFOPLIST_FILE}" 2>/dev/null)
+if [ -z "$URL" ]; then
+ URL ="http://localhost"
+fi
+
+# extract RCTPackager/port from Info.plist
+PORT=$(/usr/libexec/PlistBuddy -c "Print :RCTPackager:port" "${INFOPLIST_FILE}" 2>/dev/null)
+if [ -z "$PORT" ]; then
+ PORT="8081"
+fi
+
+export URL;
+export PORT;
THIS_DIR=$(dirname "$0")
-$THIS_DIR/packager.sh
-echo "Process terminated. Press to close the window"
-read
+
+if nc -w 5 -z localhost $PORT ; then
+ if ! curl -s "${URL}:${PORT}/status" | grep -q "packager-status:running" ; then
+ echo "Port ${URL}:${PORT} already in use, packager is either not running or not running correctly"
+ exit 2
+ fi
+else
+ # open w/t --args doesn't work:
+ # open $THIS_DIR/packager.sh --args --url=${URL} --port=${PORT} || echo "Can't start packager automatically"
+ osascript -e 'tell app "Terminal"
+ do script "'$THIS_DIR'/packager.sh --url='${URL}' --port='${PORT}'"
+ end tell' || echo "Can't start packager automatically"
+fi
\ No newline at end of file
diff --git a/packager/packager.js b/packager/packager.js
index a543aba0243af1..335bd575d34a05 100644
--- a/packager/packager.js
+++ b/packager/packager.js
@@ -37,6 +37,10 @@ var parseCommandLine = require('./parseCommandLine.js');
var webSocketProxy = require('./webSocketProxy.js');
var options = parseCommandLine([{
+ command: 'url',
+ default: 'http://localhost',
+ type: 'string',
+}, {
command: 'port',
default: 8081,
type: 'string',
@@ -116,7 +120,7 @@ if (options.assetRoots) {
checkNodeVersion();
console.log(formatBanner(
- 'Running packager on port ' + options.port + '.\n'+
+ 'Running packager on ' + options.url + ":" + options.port + '.\n'+
'\n' +
'Keep this packager running while developing on any JS projects. Feel free ' +
'to close this tab and run your own packager instance if you prefer.\n' +
@@ -195,7 +199,7 @@ function getDevToolsLauncher(options) {
res.writeHead(200, {'Content-Type': 'text/html'});
fs.createReadStream(debuggerPath).pipe(res);
} else if (req.url === '/launch-chrome-devtools') {
- var debuggerURL = 'http://localhost:' + options.port + '/debugger-ui';
+ var debuggerURL = options.url + ':' + options.port + '/debugger-ui';
var script = 'launchChromeDevTools.applescript';
console.log('Launching Dev Tools...');
childProcess.execFile(path.join(__dirname, script), [debuggerURL], function(err, stdout, stderr) {
diff --git a/packager/packager.sh b/packager/packager.sh
index 95cd8ce1e60c10..826db5fe28e5bc 100755
--- a/packager/packager.sh
+++ b/packager/packager.sh
@@ -7,6 +7,10 @@
# 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.
+# Set terminal title
+echo -en "\033]0;React Packager\a"
+clear
+
if [ $REACT_PACKAGER_LOG ];
then
echo "Logs will be redirected to $REACT_PACKAGER_LOG"