React-Native发布模式下iOS出现"No bundle url present"的错误

6
我有一个原生的iOS应用,我们使用react-native来嵌入类似Facebook的社交动态。为了运行调试模式,我使用打包服务器和以下代码:
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://X.X.X.X:8081/index.ios.bundle?platform=ios"];

bridgeReactView = [[RCTBridge alloc] initWithBundleURL: jsCodeLocation
                                        moduleProvider: nil
                                         launchOptions:nil];

rootReactView = [[RCTRootView alloc] initWithBridge:bridgeReactView
                                         moduleName:@"SocialFeed"
                                  initialProperties:@{}];

其中X.X.X.X是我的本地IP地址。这个方法很好用,但我无法将react代码捆绑到发布版本中。从官方文档和其他Stack Overflow帖子中,我了解到最初需要手动使用类似以下的方式捆绑代码:

react-native bundle --entry-file="index.ios.js" --bundle-output="./ios/MyApp/main.jsbundle' --dev=false --platform='ios' --assets-dest="./ios"

并将上面的jsCodeLocation定义更改为

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

显然,在react-native的较新版本中,如果您选择发布构建配置,xCode会自动为您捆绑代码,因此您必须将上述内容更改为:
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

对于我们来说,这两种方法都不起作用——在这两种情况下,jsCodeLocation都会被设为nil,并且我会收到“没有捆绑包URL”错误:

2017-05-08 15:06:56.738 [fatal][tid:main] No bundle URL present.

Make sure you're running a packager server or have included a .jsbundle file in your application bundle.

顺便提一下,我已经尝试在我的Info.plist文件中设置以下值:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSAllowsArbitraryLoadsInWebContent</key>
        <true/>
        <key>NSAllowsLocalNetworking</key>
        <true/>
    </dict>
</key>

你是否已经添加了React Native代码和图片的捆绑包? - Codesingh
3个回答

17

你需要执行以下步骤:

  1. 运行以下命令:react-native bundle --dev false --platform ios --entry-file index.ios.js --bundle-output ios/main.jsbundle --assets-dest ./ios
  2. 将 main.jsbundle 和 assets 目录通过拖拽添加到你的项目中。

注意:只有第一次需要执行第二步。


Mina,感谢你提供的解决方案。我花了将近两天的时间才解决了这个问题。 - Muhammad Ahsan
1
如何在 CI 环境中强制执行这个任务,有什么建议吗? - Walter Martin Vargas-Pena
该死!我已经折腾了几个小时了!非常感谢,伙计。我不明白为什么这不在React Native文档中... - thibaut noah
虽然这解决了我的问题,但感觉只是暂时的。我现在有两个 main.jsbundle 文件。我可以删除项目文件夹中的一个吗?assets 文件夹包括一些节点模块,每次添加新模块时我都需要运行此命令并手动将资产拖到项目根目录中吗? - ronnyrr
我必须先打开Xcode并创建一个空文件'main.jsbundle',然后运行上面的命令。谢谢! - Anh Duy

3
Mina M的答案对我来说非常接近,但是当我调用命令时,出现了“在任何项目根目录中找不到文件:index.ios.js”的错误。原因是因为我不再拥有Android和iOS的单独index.js文件——我只有一个(我认为这是标准做法?)。
解决方法是,在React Native项目的根目录(具有android、ios和node_modules文件夹的文件夹)中运行以下命令:
``` react-native bundle --dev false --platform ios --entry-file index.js --bundle-output ios/main.jsbundle --assets-dest ./ios ```
然后您需要执行第二步,将刚刚在ios文件夹中创建的main.jsbundle文件和assets文件夹拖入Xcode中的项目根目录。

0

在你的代码中,你声明了你的捆绑包在:

http://X.X.X.X:8081/index.ios.bundle?platform=ios

但如果它是本地IP或无法从外部网络访问,而不是您的开发环境,则捆绑URL可能会导致此类问题。


嗨,Yagiz,感谢您的评论。这是我们唯一可行的方法。我们知道在未连接到本地网络时它无法工作,这就是为什么我们想将React代码捆绑到应用程序中的原因 - 这样我们就可以在未连接到React Native打包服务器时使用我们的应用程序。 - Peter Evan Deal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接