如何使用 Xcode Targets 管理開發和生產版本?

在開始此教程以前,咱們假設你已經完成了應用程序的開發和測試,如今準備提交生產發佈。問題是,某些 Web 服務 URLs 指向測試服務器,而 API keys 則爲測試環境而配置。在提交應用程序給蘋果審覈以前,你須要修改全部這些 API keys 和 URLs以適應生產環境。這很正常,對吧?可是,除了將這些值在開發和生產環境之間來回更改,是否存在更好的方法來管理開發和生產版本呢?這正是筆者將與你討論的。html

下面開始咱們的教程!ios

首先,大家中的一些人可能想知道爲何在開發應用時,要使用兩個單獨的數據庫和環境。緣由是,隨着你持續不斷的構建新的功能或開發應用,你想確保開發版本和現有的生產版本相互區分。標準軟件開發過程旨在針對軟件(在咱們的案例中,即爲iPhone應用)的不一樣版本,使用不一樣的環境。開發版本的應用一般使用一個不一樣於生產版本的數據庫(或其餘系統,好比分析)。這就是爲何咱們應該在不一樣的環境中使用不一樣的服務器和數據庫。開發人員一般在測試期間使用虛擬圖像或數據。在測試或開發環境中,一般會使用一些測試數據,好比「test comment」,「argharghargh」和「one more test comment」。很明顯,你可不但願真實用戶看到這樣的消息。若是你的應用使用了分析系統,你可能在測試階段發送成千上萬的事件。一樣,你不想在同一個數據庫中混合測試數據和生產數據。這就是爲何老是推薦使用相互獨立的開發和生產環境。git

在使用兩個獨立的環境時,你的應用須要一種方法來找出它應該鏈接的環境。一個經常使用的方法是在主app delegate中定義一個全局變量,將應用初始化爲開發或生產模式。github

enum environmentType {
   case development, production
}

let environment:environmentType = .production

switch environment {
case .development:
    // set web service URL to development
    // set API keys to development
    print("It's for development")
case .production:
    // set web service URL to production
    // set API keys to production
    print("It's for production")
}

這種方法須要你在每次切換環境時,改變全局變量。儘管還算快速和方便,這種方法也有一些重大的限制。首先,由於咱們在開發和生產環境中使用同一個bundle ID,你不能在同一個設備上安裝兩個應用版本。當你想在同一臺設備上測試應用的開發版本,但目前仍在使用應用的生產版本時,這就很是不方便。此外,這種方法可能會意外地將應用的開發版本發佈到應用商店。若是你忘了改變單一的全局變量,你就會發布錯誤的應用程序。筆者記得有一次在應用提交以前,忘記改變全局變量,用戶得到的就是應用的開發版本。那簡直是一場災難。web

在本文中,筆者將向你展現一個更好的方法,來區分開發和生產版本。具體來講,咱們將在XCode中建立一個開發Target。此方法同時適用於新的,和現有的大型項目,因此你可使用一個現有的應用程序,來學習本教程。數據庫

經過使用這種方法,應用的生產和開發版本將具備相同的基礎代碼,但能夠有不一樣的圖標,bundle ID,並指向不一樣的數據庫。發佈和提交過程很是簡單。最重要的是,測試人員和經理能夠在同一設備上,安裝應用程序的兩個版本,因此他們徹底清楚正在測試的是哪一個版本。swift

如何建立一個新的Target

如何在Xcode中建立一個開發Target?筆者將使用本身的模板項目「todo」,逐步演示整個過程。你可使用本身的項目,循序漸進便可:api

  1. 在Project Navigator面板中找到項目設置。在Targets區域,右鍵單擊現有target,並選擇Duplicate複製現有的target。xcode

enter image description here

  1. Xcode會問你,新target是否爲iPad而開發。對於本教程,咱們選擇 「Duplicate Only」。
    enter image description here性能優化

Note: If your project supports universal devices, Xcode will not prompt the above message.

注意:若是你的項目支持通用設備,Xcode則不會提示上述消息。

  1. 如今,咱們有了一個新的target,和一個新的構建scheme,名爲todo copy。讓咱們對它重命名,使其更容易理解。

    • Select the new target in the TARGETS list. Press Enter to edit the text and put a more appropriate name. I prefer 「todo Dev」. You’re free to choose whatever name you like.

    • 在TARGETS列表中,選擇新的target。按Enter鍵來編輯文本,選擇一個更合適的名字。筆者更喜歡「todo Dev」。你能夠自由選擇任何你喜歡的名字。

    • Next, go to 「Manage Schemes…」, select the new scheme you created in step 1 and press 「Enter」. Make the scheme name the same as the new target name (which is the one you choose for the new target.)

    • 接下來,選擇「Manage Schemes…」,選擇你在步驟1中建立的新scheme,按下「Enter」。使scheme名稱和新的target名稱同樣(也就是你爲新target選擇的名稱。)

enter image description here

  1. 步驟4是可選的,但強烈推薦。若是你想簡單的區分開發和生產版本,你應該爲每一個版本使用單獨的圖標和啓動屏幕。這將使你的測試人員很清楚地知道他們正在使用哪一個應用,防止你發佈開發版本的應用。:)

Go to Assets.xcassets and add a new icon. Right click icon > App Icons & Launch Images > New iOS App Icon. Rename the new icon to 「AppIcon-Dev」 and add your own images.
選擇Assets.xcassets,並添加一個新的圖標。右擊icon> App Icons & Launch Images > New iOS App Icon。將新圖標重命名爲「AppIcon-Dev」,而後添加本身的圖片。
enter image description here

5.如今回到項目設置,選擇你的開發target,並更改bundle identifier。好比,你能夠在原ID上簡單地添加「Dev」。若是你執行了步驟4,確保你把應用圖標設置爲在上一步中建立的那個。
enter image description here

6.Xcode 將爲你的target自動添加plist文件 (好比todo copy-Info.plist)。你能夠在項目的根目錄中找到它。將它從「copy」重命名爲「Dev」,並將其保存在原始的plist文件下。這樣,你就能方便管理文件。

7.如今打開開發target 的「Build Settings」,滾動到「Packaging」,將值更改成開發plist文件(好比todo Dev.plist)。
enter image description here

8.最後,咱們將爲生產和開發targets配置一個預處理宏/編譯器標記。這樣,以後咱們就能夠在代碼中使用標記來檢測正在運行的是應用程序的哪一個版本。

對於Objective - C項目,選擇Build Settings,滾動到Apple LLVM 7.0 - Preprocessing。展開Preprocessor Macros,添加Debug和Release fields變量。對於開發target (好比todo Dev),將值設置爲DEVELOPMENT=1。換句話說,將值設置爲DEVELOPMENT=0來表示生產版本。
enter image description here
enter image description here

對於Swift項目,編譯器再也不支持預處理器指令。相反,它使用編譯時屬性和構建配置。添加一個標識,來標示開發版本,選擇開發target。選擇Build Settings和向下滾動到Swift Compiler—Custom Flags部分。將值設置爲-DDEVELOPMENT來標示target爲開發版本。
enter image description here

如今,你已經建立和配置完成開發target,下一步是什麼?

使用target和宏

經過配置宏DEV_VERSION,咱們能夠在代碼中使用它,爲你的項目執行動態編譯。下面是一個簡單的例子:

Objective-C:

#if DEVELOPMENT 
#define SERVER_URL @"http://dev.server.com/api/" 
#define API_TOKEN @"DI2023409jf90ew" 
#else 
#define SERVER_URL @"http://prod.server.com/api/" 
#define API_TOKEN @"71a629j0f090232" 
#endif

In Objective-C, you can use #if to check the condition of DEVELOPMENT, and set up the URLs/API keys accordingly.
在Objective - C中,你可使用#if檢查DEVELOPMENT的狀況,並相應地設置URLs/API keys。

Swift:

#if DEVELOPMENT
let SERVER_URL = "http://dev.server.com/api/"
let API_TOKEN = "DI2023409jf90ew"
#else
let SERVER_URL = "http://prod.server.com/api/"
let API_TOKEN = "71a629j0f090232"
#endif

在Swift中,你仍然可使用#if爲動態編譯評估構建配置。然而,不是使用# define來定義原始常量,在Swift中,咱們簡單地使用let來定義全局常量。

注意:一般狀況下,你應該把上面的代碼放入app delegate。但實際上取決於你在哪裏初始化應用的設置。

如今,當你選擇「todo Dev」 scheme,並運行這個項目,你將自動建立開發版本,服務器配置設置爲開發環境。你如今能夠向TestFlight或HockeyApp上傳開發版本,供你的測試人員和管理人員進行測試。

以後,若是你須要建立一個生產版本,簡單地選擇「todo」 scheme 便可。不須要任何代碼更改。

管理多個Targets的一些提示

1.當你將新文件添加到項目時,別忘了同時選擇兩個Targets,保持代碼在兩個版本中同步。
enter image description here

2.若是你使用Cocoapods,別忘了將新的target添加到podfile。你可使用 link_with來指定多個targets。你能夠進一步查詢Cocoapods documentation瞭解更多細節。你的podfile看起來應該像這樣:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.0'
workspace 'todo'
link_with 'todo', 'todo Dev'
pod 'Mixpanel'
pod 'AFNetworking'

你以爲本教程如何?你是如何管理開發和生產版本的?請和我分享你的想法。

原文地址:http://www.appcoda.com/using-xcode-targets/

OneAPM Mobile Insight ,監控網絡請求及網絡錯誤,提高用戶留存。訪問 OneAPM 官方網站感覺更多應用性能優化體驗,想閱讀更多技術文章,請訪問 OneAPM 官方技術博客

本文轉自 OneAPM 官方博客

相關文章
相關標籤/搜索