这几天,打算把之前集合到原生项目中的React Native项目在真机上跑跑,顺便试下发布更新等,理清以后的发布流程。。。结果,就一直卡在真机调试上了,明明在网络上一堆,都是超简单的替换localhost就行。。结果结果,试了好久,终于解决了。
正常方案(React Native 0.29.0之前版本)
首先,你要让调试用电脑和你的手机必须处于相同的 WiFi 网络中下
打开 iOS 项目的 AppDelegate.m 文件
更改 jsCodeLocation 中的 localhost 改成你电脑的局域网IP地址(查看IP地址:点击设置->网络->就可以看到本机IP)
NSURL *jsCodeLocation;
jsCodeLocation = [NSURL URLWithString: @"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
//
// 将localhost换成局域网中主机Mac的IP地址
jsCodeLocation = [NSURL URLWithString: @"http://10.10.10.60:8081/index.ios.bundle?platform=ios&dev=true"];
- 在 Xcode 中,选择你的手机作为目标设备,Run 即可
可以通过晃动设备来打开开发菜单(重载、调试等)
然后发觉,我试了n久,一直失败,提示无连接到服务器。
感觉这个方法在iOS9之前应该都是可以成功的。
原因如下:
Google后查证,iOS9引入了新特性App Transport Security (ATS)。详情:App Transport Security (ATS)。
新特性要求App内访问的网络必须使用HTTPS协议。
(下文提供解决方案)
React Native 0.29.0之后版本方案
React Native iOS在0.29.0版本中BundleURL加载方法做了重大改变,新增了RCTBundleURLProvider单例类专门处理BundleURL,使用NSUserDefaults保存配置信息。
默认加载方式
在Debug模式下,执行react-native-xcode.sh编译脚本会自动获取当前网卡en0的IP地址,并打入App包中一个配置文件ip.txt,App运行时会读取ip文件,自动生成Developer Server URL,通过这种加载方式,我们不再需要手动去把”localhost”改成Mac的IP了,每次编译都会读取当前最新的IP。
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
手动设置IP
RCTBundleURLProvider在接口中暴露了jsLocation属性,可以通过setJsLocation手动设置IP。(如果只是本地调试的话,其实没有必要手动设置哈,因为默认加载方式就回读取当前最新的IP)
// 调用前先设置IP
[[RCTBundleURLProvider sharedSettings] setJsLocation:@”10.10.10.60”];
App Transport Security 设置
上面两种不同的方案主要是针对React Native不同版本做的区分,,推荐使用第二种方案,比较简单直接。
不过如果是iOS9的话,估计上面的方案均没有让你真的调试成功,原因在于:
iOS9引入了新特性App Transport Security (ATS)。详情:App Transport Security (ATS)。
新特性要求App内访问的网络必须使用HTTPS协议。(如果直接用IP地址发出http请求失败的话大多数原因也是这个,同下解决办法)
解决办法:
需要在Info设置NSAppTransportSecurity的NSAllowsArbitraryLoads为true
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
效果如下:
花费了几天的时间弄真机测试和打包更新,因为网上查到的资料大多是以前的,而NSAppTransportSecurity又是iOS9的新特性,这个真的很重要哈,所以就作为一个插曲插进原本有规划的写作,分享下,希望读者不用走这歪路。。。如果还是调试失败的话欢迎留言讨论下哈哈。