一位没有mac,没有ios开发经验的农民,如何通过ReactNative开发ios应用并打包?

表情包.jpg

资源准备

苹果环境

ios和android不同,打包需要借助Xcode,而Xcode又只能在MacOS上运行。
我们有三种方法,买一台苹果电脑、装黑苹果、虚拟机装MacOS。
第一种不考虑,第二种很麻烦,如果只是打包ios应用的话,虚拟机即可,参考VMware 安装黑苹果

一定要注意版本问题,请根据自己项目的RN版本确定Xcode版本再确定MacOS版本,嫌麻烦请直接安排最新版本,很多问题都是版本问题或者新版本已经修复的问题。

NodeJs环境

尽管只是打包ios应用,但还是需要要NodeJs环境。并且打包时仍然需要整个完整的项目文件夹,而不只是项目下的ios文件夹。安装NodeJsreact-native cliyarn

证书、签名

android打包也是需要证书的,只不过通过java命令行一键就生成了,而ios的证书需要去苹果官网申请,申请的条件是交了600块钱一年的开发者费用。没有证书就找别人借一个。。。
如果开发的应用是正规应用,打包完后就提交app store审核就是了,如果不是正规的话。。。找第三方企业签名,他们会用企业证书覆盖你的证书,然后就可以在任意ios设备上安装了。

导入证书

证书文件应该有以下两个文件,一个.p12和一个.provision

证书文件.jpg

双击.p12文件,依提示输入用户密码和证书密码即可导入。在钥匙串访问-系统中能找到刚才导入的证书。

导入证书.jpg

Xcode打开RN项目中的ios文件夹,在文件列表中双击蓝色的这一行。

ios.jpg

在弹出的.xcodeproj窗口中,修改Bundle Identifier为你证书的APP IDS(这里不修改,下面也会报错提示你修改),然后去掉Automatically manage signing的勾选。

xcodeproj.jpg

去掉勾选后会出现下面两个栏目,打开Provisioning Profile下拉栏,选择import Profile,然后选择证书文件夹中的.provision文件。

选择证书.jpg

证书无误且成功导入系统后,这时应该会这样,如果上面的Bundle Identifier没有修改,这里会报红提示你修改。

导入成功.jpg

到这里证书已经成功导入了可以准备打包了。

离线js包

我们在Debug调试的时候,能看到这样一个终端,称它为Node服务器,我们还可以看到它在加载js文件,所以我们在调试的时候可以做到热更新代码。但是到了正式环境,手机上是没有Node服务器的,所以我们需要把js文件打包成静态离线包,这样就不需要借助Node服务器了。

node服务器.jpg

打开项目文件夹下的package.json,在scripts中添加

"bundle-ios": "node node_modules/react-native/local-cli/cli.js bundle --entry-file index.js  --platform ios --dev false --bundle-output ./ios/bundle/index.ios.jsbundle --assets-dest ./ios/bundle"

然后在ios文件夹下添加文件夹bundle。最后打开终端,cd到项目文件夹下,执行npm run bundle-ios。就能在ios文件夹下的bundle里看到生成的离线文件,包括js文件和用到的图片字体等资源。

单单生成了离线包还不行,需要引入到Xcode项目中去。
右键项目文件夹,选择Add File to "",选择刚刚创建的bundle文件夹,并记得勾选Create folder references

Add File.jpg

项目文件夹中出现蓝色的文件夹bundle就ok了。

bundle.jpg

引入了离线包还不够,还需要修改入口,让程序使用离线包。
AppDelegate.m文件中,能看到这样一行代码,代表着程序使用Node服务器作为入口。

js入口.jpg

将其修改为

#ifdef DEBUG
  // debug包
  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  // 离线包
  jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"bundle/index.ios" withExtension:@"jsbundle"];
#endif

从字面意思也能看出来,debug时使用Node服务器,打包后使用bundle下的离线文件。

调试

虽然在Android平台上我们已经测试了千万遍,但是保证不了在ios平台上不会出问题。所以我们仍需要调试,这时黑苹果的优势就体现出来了,毕竟在虚拟机里再跑ios模拟器,小点的应用还好,大应用卡的生活不能自理。所以有时间有能力折腾的朋友建议给电脑安装黑苹果。
Xcode顶栏选择设备后启动运行就ok了。

:CFBundleIdentifier

[scode type="red"]Print: Entry, ":CFBundleIdentifier", Does Not Exist[/scode]
这是大多数人都会报的错误,原因很简答,在~/.rncache下的4个文件出问题了,多半是下载不完全的问题。

CFBundleIdentifier.jpg

参照这篇文章下载以上文件,保险点就4个文件全部重新下,要么就一个个md5码验证。
如果替换后还是出问题,请检查Xcode版本,还是那句话,嫌麻烦请直接安排最新版本。
另外这都2019年了,如果还有人说用0.44.3版本的RN的话,那也太蠢了8。

RCTBundleURLProvider.h is not found

这个报错属于正常,因为Node服务器没有启动。如果启动后仍报这个错并且build failed,请删除node_modules并重新yarn。如果仍不能解决问题,请检查Xcode版本,99%是版本的问题。

使用离线包调试

如果跑起来了,那么恭喜你,离打包成功已经很近了,跑不起来的请自行查找报错原因。
使用Node服务器能跑起来,那正式环境使用离线包会不会出问题呢?我们也是可以使用离线包进行调试的。
打开Product-Scheme-Edit Scheme-Run
Build Configuration改为Release。代表在Debug时采用Release的模式。

Release.jpg

再次运行,可以看到Node服务器中没有加载js,程序仍然跑起来了。调试正常就可以进入最后一步打包了。

离线js包.png

打包

在选择设备的地方选择Generic iOS Device

ios设备.jpg

然后点击Product-Archive,开始打包。打包完成后如下,如果要上传app store,直接点蓝色按钮就行。如果要通过第三方企业签名发行的话,点击Export

上传app store.jpg

这里根据证书选择,我的是Development。

证书类型.jpg

一路下一步,到这里后,如果.app里没有东西,请再Import Profile一下证书文件夹里的.provision文件,一路下去就打包成功了。

Import Profile.jpg

如果切换为release进行调试程序运行正常,但企业签名后,程序闪退,99.9%是打包证书问题,换个证书尝试