React Native (二) ios打包到真機

每當在模擬器上完成了開發,都想到真機上試試,正好前段時候淘了一個imac。

這裏就以打包rndemo到iphone爲例,講一下react ntive ios打包到真機的流程。

 

一、前置

1.有個iphone加個mac

2.首先react native的環境要正確安裝,還未完成這一步的,請到react native官網或中文站查看具體流程

3.xcode等環境安裝完畢

4.rn應用能在模擬器中跑起來,至少不要有什麼致命報錯吧

 

二、生成jsbundle

1.進入rn項目的ios工程文件夾,找到和rn項目同名的文件夾,打開AppDelegate.m文件,將這一行註釋掉(爲了方便真機和模擬器間的切換,儘量註釋):

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

新加一行:

jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index.ios" withExtension:@"jsbundle"];

如果需要切換回模擬器調試,只需要將新加這行註釋掉,並恢復原代碼即可。

新加這行代碼大概意思就是告訴native rn代碼的入口,我們會在下一步生成這個jsbundle。

 

2.打開終端,進入你的rn工程,在根目錄下執行bundle命令:

react-native bundle --entry-file ./index.ios.js --bundle-output ./ios/bundle/index.ios.jsbundle --platform ios --assets-dest ./ios/bundle --dev false

參數說明:

--entry-file 指定入口文件 因爲要打包ios平臺,所以指定爲rn項目的index.ios.js作爲入口

--bundle-output 指定輸出的jsbundle文件路徑和文件名 指定到rn項目的ios工程文件夾下,記得一定要先創建bundle文件夾,不然終端會報文件夾找不到的錯誤

--platform 指定平臺類型

--assets-dest 指定資源文件夾路徑 assets文件夾的路徑,包含圖片、node模塊等資源

--dev 是否爲開發模式 如果設置爲false,不會產生警告,並且bundle會被壓縮

還有其他命令,比如:transformer、prepack、bundle-encoding等,可以到官網查看具體介紹。

 

bundle生成完成後,終端會有類似提示:

 

 

3.用xcode Open another project打開rn項目的ios工程文件夾:

 

 

 

 

 將之前打包好的jsbundle和assets拖入rndemo這個文件夾下面,注意一定要選擇 Create folder references:

 

三、配置網絡訪問白名單

應用中如果有網絡請求,這一步必不可少,要不然會出現網絡請求失敗的錯誤提示。

1.打開Info.plist:

2.在App Transport Security Settings下添加key:Exception Domains,類型爲Dictionary。

3.在Exception Domains下添加你的應用可能會訪問到的域名,key爲域名,類型爲Dictionary。需要注意的是:

iOS 9及以上版本,非HTTS的網絡是被禁止的,當然我們也可以把NSAllowsArbitraryLoads設置爲YES禁用ATS。不過iOS 10從2017年1月1日起蘋果不允許我們通過這個方法跳過ATS,也就是說強制我們用HTTPS,如果不這樣的話提交App可能會被拒絕。但是我們可以通過NSExceptionDomains來針對特定的域名開放HTTP可以容易通過審覈。每個域名都需要三個屬性,key分別爲:

NSIncludesSubdomains 是否包含子域 設置爲true

NSExceptionRequiresForwardSecrecy 指定域名是否支持Forward Secrecy 設置爲false

NSExceptionAllowsInsecureHTTPLoads 是否能使用http協議,默認是隻能請求https的 設置爲true

類型都爲Boolean。

比如這裏,我增加了api.douban.com這個白名單域,因爲它本身就是走的https協議,那三個子屬性我便沒再做配置。應用需要訪問的域都可以加到這裏。

 

如果進入應用以後,依然無法請求網絡,請檢查 通用->蜂窩移動網絡->使用無線局域網與蜂窩移動的應用->你的應用  設置允許的數據使用。

 

四、設置應用圖標和閃屏圖片(啓動圖)

在xcode中點擊Images.xcassets文件夾,這是保存應用圖標和閃屏等的文件夾:

 

可以看到應用圖標是按照尺寸分類了的,具體每個類型的圖片大小要求可以自行查找資料,一定要保證同樣的分辨率,而且不需要是圓角,否則在編譯的時候會有警告提示。

閃屏的話,可以右鍵添加LaunchImage,也是同樣的按尺寸和方向分類的,只需要拖入對應的圖片即可。

圖標和啓動圖我都是胡亂弄的,要弄齊所有還是很麻煩。 

 

五、連接iphone到電腦,並讓它們處於wifi的同一網段

1.連接好iphone以後,將設備選擇爲你的iphone,並點擊xcode左上方的build按鈕,就可以執行構建了:

 

 2.構建完成以後,xcode會有個沒法啓動應用的提示。原因是你的手機沒有信任這個程序,在手機設置中:通用->設備管理->開發者應用 中信任這個應用,然後點擊應用圖標即可啓動應用了。

 

構建中途可能會有錯誤或者警告提示,可根據具體的提示查找解決辦法。

我遇到過兩個錯誤:

1.app id不唯一,在這裏可以重新設置:

 

2.簽名那裏沒有指定一個team:

 

在這裏可以按照提示一步一步設置

 

還需要注意的是部署的目標要和iphone系統版本一致:

 

對於native小白來說,這些的確很陌生,哈哈

 

六、簡化bundle命令

react-native的bundle子命令有太多的參數需要設置,但是我們每次打包新bundle並需要改變什麼,至少大多數情況是這樣的。觀察raect-native的node_modules依賴,發現已經安裝了yargs和shelljs,這是其他包間接依賴的。這兩個模塊可以幫助我們創建自己的bundle命令行工具。以前正好看過這兩個包的介紹,這裏正好用上。

簡短介紹:

yargs 可以幫助我們分析和整理命令的參數,比直接操作process.argv數組要方便得多,定製性也很強。

shelljs 提供了調用shell命令的能力,能夠在js中書寫shell腳本,是對child_process的擴展。

 

命令行製作步驟:

1.創建命令行文件

我們在rn項目的根目錄創建一個mkbundle.js的文件,文件開頭加上  #!/usr/bin/env node ,指定使用node來執行這個文件,注:這僅僅是類unix系統的方式,windows系統請使用bat來啓動,或者使用powershell來執行,這需要win7以上支持。

 

2.修改package.json文件

加入一個bin屬性,值爲一個對象

"bin": {
    "mkbundle": "./mkbundle.js"
},

 

3.執行 npm link 命令

完成以後,在rn項目的根目錄,mkbundle就成爲了一個在終端裏可執行的全局命令,關於link命令,這裏有篇不錯的文章

 

4.測試

在mkbundle.js中加入一行測試代碼 console.log(123); ,並執行 mkbundle 命令,

可以看見123被輸出出來了,配置到這裏就成功了。下面是命令行工具的實現:

 

5.實現這個工具

 1 #!/usr/bin/env node
 2 
 3 /**
 4  * '$ mkbundle'
 5  * 用途:簡化jsbundle打包命令
 6  * 作者:james
 7  * 依賴:yargs、shelljs兩個包。rn項目默認會有包依賴這兩個包,在項目初始化完畢並執行‘npm install’後,不需要再手動安裝
 8  * 使用:進入終端,切換目錄至rn項目的根目錄,即本js文件所在目錄,執行mkbundle命令即可
 9  * 說明:本命令行工具代理了react-native命令下的bundle子命令的5個最常用參數,這5個參數均已設置默認值,都可以不傳,也可以只傳某些需要改變的值
10  *
11  * bundle子命令的所有參數:
12  *
13  * --entry-file        指定js入口文件的路徑  [已代理,簡寫爲 -ef]
14  * --platform          指定設備平臺類型  [已代理,簡寫爲 -p]
15  * --transformer       指定一個自定義的轉換器
16  * --dev               如果爲否,將關閉警告並壓縮bundle文件  [已代理]
17  * --prepack           如果爲真,將輸出預打包格式的bundle
18  * --bridge-config     指定bridge json配置文件的名稱
19  * --bundle-output     指定bundle文件的輸出路徑  [已代理,簡寫爲 -bo]
20  * --bundle-encoding   指定bundle文件的編碼格式
21  * --sourcemap-output  指定soucemap的文件名稱及路徑
22  * --assets-dest       指定資源文件夾的輸出目錄 [已代理,簡寫爲 -ad]
23  * --verbose           如果爲真,將記錄日誌
24  */
25 
26 require('shelljs/global');
27 
28 if (!which('react-native')){
29     echo('請先安裝react-native-cli');
30     exit(1);
31 }
32 
33 const {ef, bo, ad, p, dev} = require('yargs')
34     .option('entry-file', {
35         alias: 'ef',
36         demand: false,
37         default: './index.ios.js',
38         describe: '指定js入口文件的路徑',
39         type: 'string'
40     })
41     .option('bundle-output', {
42         alias: 'bo',
43         demand: false,
44         default: './ios/bundle/index.ios.jsbundle',
45         describe: '指定bundle文件的輸出路徑',
46         type: 'string'
47     })
48     .option('assets-dest', {
49         alias: 'ad',
50         demand: false,
51         default: './ios/bundle',
52         describe: '指定資源文件夾的輸出目錄',
53         type: 'string'
54     })
55     .option('platform', {
56         alias: 'p',
57         demand: false,
58         default: 'ios',
59         describe: '指定設備平臺類型',
60         type: 'string'
61     })
62     .option('dev', {
63         alias: 'dev',
64         demand: false,
65         default: false,
66         describe: '如果爲否,將關閉警告並壓縮bundle文件',
67         boolean: true,
68         type: 'boolean'
69     })
70     .help('help')
71     .alias('help', 'h')
72     .argv;
73 
74 rm('-rf', './ios/bundle');
75 mkdir('-p', './ios/bundle');
76 
77 if (exec(`react-native bundle --entry-file ${ef} --bundle-output ${bo} --assets-dest ${ad} --platform ${p} --dev ${dev}`).code != 0){
78     echo('錯誤:bundle 失敗');
79     exit(1);
80 }

 

可以看到,我把bundle命令最常用的5個參數做了代理,並設置了別名來簡化輸入。執行 mkbundle 命令的時候,甚至可以什麼參數都不輸入,因爲它們都指定了默認的值。如果某些參數值需要修改,只需單獨設置這些參數的值即可。

參數的默認值可以根據自身項目情況和Appdelegate.m的配置來設置。

這個工具目前只是一個雛形,可以根據我們的需要進行擴展,畢竟yargs和shelljs的配合提供了很強大的功能。

執行 mkbundle --h 命令,可以看到幫助信息,如果你有合作的夥伴或者某一天會publish這個工具,這對使用者會有幫助:

 

 

執行 mkbundle 命令,和我們手動輸入 react-native bundle --xxx xx --xxx -xx ...  的結果是一樣的,路徑以及文件都被正確的創建出來了:

 

 

快去構建你的APP吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章