The official React Native documentation to run app on iOS device using offline bundle says
Open ios/YourApp/AppDelegate.m
Uncomment the line, jsCo
EDIT: The whole bundle ip detection should be automatic on the latest release of react-native. If you select your device on xcode do build and run
and run the app once. It should save an offline bundle on the phone so that if it doesn't find a packager server running, it will use the offline bundle.
source: https://github.com/facebook/react-native/commit/8c29a52c54392ce52148e7d3aa9f835537453aa4
If you change to a release
scheme while building your app, that will compile your app with the offline bundle.
Product > Scheme > Edit Scheme > set build configuration
to Release
.
Not sure why they didn't update the documentation for the Appdelegate.m
method. Looks like the line is still there on the sources. [Edit: there's a pull request for this]
First I would make sure I have ios-deploy
installed.
You can do so by running npm install -g ios-deploy
Then connect the iphone you want the app to be installed in into your mac.
Then run
react-native run-ios --device "ABC’s iPhone" --configuration=release
This would create a offline js bundled app and install it onto the iphone.
PS: If it errors out saying
Signing for "<app name>" requires a development team.
Select a development team in the project editor.
Then open up the project inside ios/
in Xcode and
Select the target -> General Tab
Under signing choose the signing team and choose automatically manage signing.
Then save and re-run the command.
When I open the global proxy in ShadowsocksX, automatic IP detection won't return http://localhost:8081/index.ios.bundle
in the debug mode.
That's why the URL for main.jsbundle returned as null
.
How to solve?
Option 1:
replace
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
with
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
This method could disable automatic IP detection.
Option 2:
Switch your proxy mode if you open the global proxy mode.
The only fix I could get to work on react native 0.37 was to go back to the "old school" method of manually editing jsCodeLocation in AppDelegate.m. Debugging is good again!
Be sure your device and development machine are on the same wi-fi, and maybe disconnect any wired Ethernet until you get it working.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
// Comment-out, cannot get past error: bundleURL must be non-nil when not implementing loadSourceForBridge
//jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
#if DEBUG
NSLog(@"AppDelegate:DEBUG");
#if TARGET_IPHONE_SIMULATOR
NSLog(@"AppDelegate:DEBUG:TARGET_IPHONE_SIMULATOR");
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"];
#else
NSLog(@"AppDelegate:DEBUG:!TARGET_IPHONE_SIMULATOR");
NSLog(@"To device debug, open RCTWebSocketExecutor.m & replace localhost with MacBook IP.");
// Get dev host IP Address:
// ifconfig | grep inet\ | tail -1 | cut -d " " -f 2
jsCodeLocation = [NSURL URLWithString:@"http://192.16.29.213:8081/index.ios.bundle"];
#endif
#else
NSLog(@"AppDelegate:RELEASE jsbundle");
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
NSLog(@"jsCodeLocation = %@",jsCodeLocation);
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"BluetoothConnect"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
For me the problem was that I had fiddled with the Info.plist and removed the localhost app transport security exception. Adding this back into Info.plist fixed it for me:
<key>NSAppTransportSecurity</key>
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
tl;dr Make sure your localhost ip address is explicitly stated in your hosts file, and that your hosts file hasn't become corrupted.
So our team kept hitting this issue. It turns out that React Native reads the host file on your machine looking for the URL to store, so that it can pull the js to create an offline bundle, or to just reach the packager while the app is running on your device.
We actually weren't trying to run this as an offline bundle, just in the ios simulator, so we were left really scratching our heads. We found the fix because the needed fix was also causing other issues with react native. Our etc/hosts file on a mac didn't have the localhost ip explicitly stated. I added that in and the problem seemed to go away. Forgive me as I don't know much about osx and dns resolution but it seems that with the new automatic ip detection, this is now necessary.
I am not sure how react native is getting the ip, if it is reading the hosts file, or the host file is propogating something else in osx that rn is reading, but if the above fix doesnt work for you, I would look to see if the hosts file itself is corrupted with certain characters that cause it not to be read. In my hunting for the solution to this problem, I came across many posts and questions about malformed hosts files that caused issues with localhost being resolved properly.
Also, it seems there is an effort underway to update the ip detection, but I am not well versed enough in obj c to know if this issue would be corrected by the new code. Maybe someone can take a look? https://github.com/facebook/react-native/pull/8789
Another also, clearing your osx DNS cache may help https://coolestguidesontheplanet.com/clear-the-local-dns-cache-in-osx/