使用脱机捆绑包在iOS设备上运行react-native app

时间:2016-08-05 02:47:54

标签: react-native

使用离线版捆绑在iOS设备上运行应用的官方React Native文档说

  

打开ios / YourApp / AppDelegate.m

     

取消注释该行,jsCodeLocation = [[NSBundle mainBundle] ...

使用最新的react-native 0.30.0,此行不再出现在默认的AppDelegate.m文件中。摘自默认的AppDelegate.m文件

NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                    moduleName:@"TestAppDelete"
                                             initialProperties:nil
                                                 launchOptions:launchOptions];

如果我尝试使用以前版本中的jsCodeLocation,则返回为null

jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

我不确定为什么main.jsbundle的网址返回为null。它不是由包装商创造的。如果它也应该使用最新版本创建,我该如何确认呢?

如果您使用离线套装在iOS设备上运行了react-native 0.30.0应用,请分享相关说明。

6 个答案:

答案 0 :(得分:24)

编辑:在最新版本的react-native上,整个捆绑软件ip检测应该是自动的。如果您在xcode上选择设备,请执行build and run并运行应用一次。它应该在手机上保存一个脱机捆绑包,这样如果它没有找到运行的打包服务器,它将使用脱机捆绑包。

来源:https://github.com/facebook/react-native/commit/8c29a52c54392ce52148e7d3aa9f835537453aa4

如果您在构建应用时更改为release方案,则会使用脱机捆绑包编译您的应用。

产品>方案>编辑方案>将build configuration设为Release

不确定为什么他们没有更新Appdelegate.m方法的文档。看起来这条线仍然存在于源头上。 [编辑:此处为pull request

答案 1 :(得分:10)

当我在ShadowsocksX中打开全局代理时,自动IP检测不会在调试模式下返回http://localhost:8081/index.ios.bundle。 这就是为什么main.jsbundle的URL返回为null

如何解决?

选项1:

替换

jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];

此方法可能会禁用自动IP检测。

选项2:

如果打开全局代理模式,请切换代理模式。

答案 2 :(得分:3)

tl; dr确保在您的hosts文件中明确声明了您的localhost IP地址,并确保您的hosts文件没有损坏。

所以我们的团队一直在努力解决这个问题。事实证明,React Native会在您的计算机上读取主机文件,寻找要存储的URL,以便它可以拉动js来创建脱机捆绑包,或者只是在应用程序在您的设备上运行时到达打包器。

我们实际上并没有尝试将其作为离线捆绑包运行,只是在ios模拟器中,所以我们真的摸不着头脑。我们找到了修复程序,因为所需的修复程序也导致了本机的其他问题。我们在mac上的etc / hosts文件没有明确声明localhost ip。我补充说,问题似乎消失了。原谅我,因为我不太了解osx和dns分辨率,但似乎有了新的自动ip检测,现在这是必要的。

我不确定本机是如何获取ip,如果它正在读取hosts文件,或者主机文件正在传播正在读取的osx中的其他内容,但如果上述修复程序对你不起作用,我会查看主机文件本身是否已损坏某些导致无法读取的字符。在我寻找这个问题的解决方案时,我遇到了许多关于格式错误的主机文件的帖子和问题,导致localhost被正确解决的问题。

此外,似乎正在努力更新ip检测,但我还不太了解这个问题是否会被新代码纠正。也许有人可以看看? https://github.com/facebook/react-native/pull/8789

另一个,清除您的osx DNS缓存可能有助于https://coolestguidesontheplanet.com/clear-the-local-dns-cache-in-osx/

答案 3 :(得分:1)

唯一能解决做出反应0.37 的唯一方法就是回到旧学校"在 AppDelegate.m 中手动编辑 jsCodeLocation 的方法。调试再好!

确保您的设备和开发机器位于同一个Wi-Fi上,并且可能会断开任何有线以太网,直到您使用它为止。

- (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;
}

答案 4 :(得分:1)

对我来说问题是我摆弄了Info.plist并删除了localhost app传输安全异常。将其添加回Info.plist为我修复了它:

<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>

答案 5 :(得分:0)

首先,我将确保已安装POJO

您可以通过运行ios-deploy

然后将要安装应用程序的iPhone连接到Mac。

然后运行

npm install -g ios-deploy

这将创建一个离线js捆绑应用程序,并将其安装到iphone。

PS:如果错误说出

react-native run-ios --device "ABC’s iPhone" --configuration=release

然后在Xcode中的Signing for "<app name>" requires a development team. Select a development team in the project editor. 中打开项目,然后 选择目标->常规选项卡 在“签名”下,选择签名团队,然后选择“自动管理签名”。

然后保存并重新运行命令。