React Native — 如何管理雙平台的.env(iOS篇)

廖季威
8 min readFeb 8, 2021

--

上一篇我們介紹到Android如何設定,這篇我們會進入iOS的部分,iOS的設定會比android來的麻煩,也強制需要搭配Xcode來做設定,所以我們先打開Xcode吧!

這邊我們會使用taget來管理我們的環境,所以我們先建立一個New Group

  • 這邊我們重新命名New GroupMyAppStaging (MyApp是你App的名字,例如我的就是demoStaging)
  • 然後右鍵點Targets
    選擇Duplicate > Duplicate Only > rename to MyAppStaging
  • 然後我們為了要在同一個裝置上可以同時安裝不同環境的App,所以請在General 中把Bundle Identifier 改成com.MyApp.staging (重點是後綴加上staging)。
  • 接下來把新產出來的Info.plist 移到剛剛創出來的Group 裡面
    (請注意,要確實移到裡面去,如果單純在xcode中拖移,只會改變reference,所以要到finder中移動。),然後重新命名成Info.plist
  • 如果你的環境中有.entitlements 檔案,也請duplicate一份,並放進你的Group 中,這是為了讓你在不同環境下,有獨立的capabilities
  • 然後在剛剛新建立的MyAppStaging Target 中的Build Setting Tab裡面,搜尋Packaging ,接著把Info.plist File 指向我們剛剛建立的新的plist ,請注意要加上路徑,如範例MyAppStaging/Info.plist

如果在上個步驟你有duplicated一份.entitlements ,那麼你需要在搜尋Signing ,然後設定Code Signing Entitlements 的路徑,到你剛剛複製出來的那份.entitlements
(ex: MyAppStaging/MyAppStaging.entitlements)

  • 接著我們點左上角的Scheme,並且進到Manage Schemes… ,找到我們剛剛Duplicate出來的Scheme (應該會是MyApp copy),然後重新命名成MyAppStaging 。之後點左下角的Edit...
  • 然後在Build 裏新增React (如下圖),然後把Build OptionsParallelize Build uncheck
  • 接著展開Build ,然後在Pre-actions裡面新增一個New Run Script Action (如下圖),接著輸入script:
echo ".env.development" > /tmp/envfile
  • 接著重複上面Build 設定的部分(從新增React 那邊開始),在設定一次main target ,差異是,引入的.env不同,所以script為:
echo ".env.production" > /tmp/envfile
  • 接著因為我們也希望staging在安裝於裝置時,不需要連線到Metro Server ,所以在staging的scheme,把RunBuild Configuration 改成Release
  • 接著,我們在Duplicate一個debugTarget ,重複一次上面的步驟,請注意以下幾點:
  1. Build Pre-ActionScript 應該也是.env.development
  2. Debug的Run應該是屬於DebugBuild Configuration
  • 這樣一來,我們就有了三個TargetsScheme

然後我們為了讓裝置上,每個環境都有自己的App_Name,所以我們需要再多幾個步驟。
(以下步驟,參考ziad_tamim 大大的文章https://www.appcoda.com.tw/xcconfig-guide/)

  • 我們到PROJECT 下面的Info >Duplicate “Release” Configuration > Rename Staging
  • 接著,我們在Root 建立三個Configuration Setting File
    (請注意,案Next後,請確保Targets 不要勾選到任何一個),然後取名為
    Release DebugStaging
  • 接著到ProjectInfo ,把圖片中的三個地方,指向你剛剛創建出來的xcconfig
  • 接著進去xcconfig 裡面設定變數吧!如下:
    (APP_NAME如果有空白,會被吃掉,要注意喔!除非使用全形空白。)

Staging.xcconfig

IS_APP_NAME = Demo_Staging
IS_APP_VERSION = 0.1
IS_APP_BUNDLE_ID = com.demo.staging

Debug.xcconfig

IS_APP_NAME = Demo_Debug
IS_APP_VERSION = 0.1
IS_APP_BUNDLE_ID = com.demo.debug

Release.xcconfig

IS_APP_NAME = Demo
IS_APP_VERSION = 0.1
IS_APP_BUNDLE_ID = com.demo
  • 接著我們進去TargetsInfo 裡面,把以下三個地方,設定成環境變數看看吧。(請記得,Staging也要設定喔!)
  • 以上,就成功設定完成了!
    (如果icon部份也需要區別,請參考ziad_tamim大大的文章)

接著,我們要去設定我們的Podfile (ios/Podfile),在多個Targets 下,我們需要設定abstract_target ,我們需要把Podfile的

target 'MyApp' do

換成

abstract_target 'App' do

App可以換成任何字,但是不可以跟Targets 的名字重複。

接著我們需要define我們的targets ,這需要繼承自我們的abstract target。
因為我們現在有三個環境,所以我們需要設定三個,我們把原本裡面的MyAppTests 環境,放進Main Target中。

target 'demo' do
target 'demoTests' do
inherit! :complete
# Pods for testing
end
end
target 'demoStaging' do
#Development-specific pods
end
target 'demoDebug' do
#Development-specific pods
end

整個Podfile設定完之後,應該會如下

最後,我們再跑一次 npx pod-install ,替每個環境設定好Pod。

接著我們就可以執行了!

react-native run-ios --scheme "demoStaging"

透過改變--scheme ,我們可以執行不同的環境。

如果此時發現類似以下錯誤

這時候請到Xcode的Targets 下的Build Phases > Copy Bundle Resources > Remove Info.plist

登愣~成功的在Simulator上安裝了三個環境
也成功地看見了我們的環境變數囉!

以上就是我在RN上管理專案文件的心得,希望這個分享有幫助到大家,當然這還有更進階的運用,也歡迎有興趣,或是有大大發現問中哪裡有講解錯誤的,也麻煩指正,感謝各位看完我的文章^^

--

--