版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2021.06.09 星期三 |
前言
程序總會有bug嘹承,如果有好的調(diào)試技巧和方法浸策,那么就是事半功倍,這個專題專門和大家分享下和調(diào)試相關(guān)的技巧乔询。希望可以幫助到大家谎砾。感興趣的可以看下面幾篇文章逢倍。
1. 程序調(diào)試 (一) —— App Crash的調(diào)試和解決示例(一)
2. 程序調(diào)試 (二) —— Xcode Simulator的高級功能(一)
3. 程序調(diào)試 (三) —— Xcode Simulator的高級功能(二)
4. 程序調(diào)試 (四) —— Xcode內(nèi)存管理(一)
開始
首先看下主要內(nèi)容:
使用
Xcode build settings
和.xcconfig
文件以不同的構(gòu)建配置(build configurations)
更改應用程序的設置和圖標。內(nèi)容來自翻譯景图。
下面看下寫作環(huán)境:
Swift 5, iOS 14, Xcode 12
下面就是正文啦较雕。
Debug, test, release
—— 這些是大多數(shù)應用程序經(jīng)歷的階段。 在每個階段挚币,應用程序都有不同的構(gòu)建設置亮蒋、定義和常量。 開發(fā)人員使用debug
后端 URL 和設置構(gòu)建應用程序忘晤。 測試人員使用類似生產(chǎn)的設置測試 beta
版本宛蚓。 客戶使用具有最終生產(chǎn)設置的應用程序。
在 Xcode
中跨不同環(huán)境管理這些設置非常耗時——更不用說當您有多個targets
時增加的工作了设塔。 幸運的是凄吏,Apple 提供了一種更好的方式來處理這些設置:Xcode build configuration files, or .xcconfig files远舅。
在本教程中,您將:
- 使用
Xcode
構(gòu)建配置文件痕钢。 - 管理跨多個環(huán)境和
targets
的構(gòu)建設置图柏。 - 從代碼訪問構(gòu)建設置。
打開起始項目任连。 構(gòu)建并運行蚤吹。
您將使用的應用程序 NinjaCounter 可幫助生物學家和愛好者計算海龜孵化的數(shù)量。 該應用程序有一個視圖:CounterView.swift
随抠,用戶可以在其中記錄幼龜裁着。
在 NinjaCounter
組中,您會發(fā)現(xiàn)以下內(nèi)容:
- Hatchling:一個簡單的結(jié)構(gòu)拱她,具有孵化記錄屬性二驰。
-
UserDefaultsHelper:一個
UserDefaults
助手,提供存儲和加載孵化記錄的方法秉沼。
構(gòu)建并運行桶雀。 在tag text field
中,輸入 Leonardo
唬复。 點擊+ Hatchling
按鈕矗积。
這樣,您就創(chuàng)建了一個帶有孵化標簽和孵化時間的新記錄敞咧。
現(xiàn)在您已經(jīng)了解了入門項目的要點棘捣,您將設置app widget
。
Setting Up Widget with App Group
打開 Widget.swift
并查看代碼妄均。 它創(chuàng)建了一個簡單的widget
柱锹,顯示計數(shù)的孵化數(shù)量和報告的最后一個孵化的標簽。
在 getTimeline(in:completion:)
中丰包,widget
使用 UserDefaultsHelper
的 getRecordsCount()
和 getRecords()
從 UserDefaults
獲取數(shù)據(jù)。
選擇 WidgetExtension scheme
壤巷。 構(gòu)建并運行邑彪。
目前,即使您剛剛錄制了 Leonardo
胧华,該widget
也不顯示任何數(shù)據(jù)寄症。 這是因為擴展程序無權(quán)訪問應用程序的 UserDefaults
。 要解決此問題矩动,您需要將應用程序和小部件添加到app group
有巧。
在項目導航器中選擇 NinjaCounter
項目以顯示Project Editor
。 選擇 NinjaCounter target
悲没。 打開Signing & Capabilities
選項卡篮迎。
選擇development team
進行簽名。
將Bundle Identifier
更改為您獨有的內(nèi)容,例如 com.myorg.NinjaCounter
甜橱。 請記住這一點逊笆,因為您將再次需要它。
單擊+ Capability
岂傲。 雙擊App Groups
难裆。
現(xiàn)在您已將App Groups
添加到capabilities
中,單擊 +
按鈕創(chuàng)建app group
镊掖。 您將看到輸入組名稱的提示乃戈。
輸入group
,單擊OK
亩进。
現(xiàn)在症虑,對 Widget Extension target
執(zhí)行相同的步驟。 確保bundle identifier
以 .widget
結(jié)尾镐侯,但使用您為主應用程序創(chuàng)建的相同app group
侦讨。 這允許在主機應用程序和widget extension
之間共享數(shù)據(jù)。
現(xiàn)在您已經(jīng)創(chuàng)建了App Group
并將targets
添加到其中苟翻,是時候讓應用程序組訪問 UserDefaults
套件了韵卤。
打開 UserDefaultsHelper.swift
并將defaults
聲明替換為:
static private let defaults = UserDefaults(
suiteName: "<#the app group name you defined#>")
?? .standard
使用此代碼,您可以確保應用從app group
共享的 UserDefaults
套件中保存和讀取數(shù)據(jù)崇猫。 這允許widget
訪問孵化數(shù)據(jù)沈条。
將active scheme
更改為 NinjaCounter
。 構(gòu)建并運行诅炉。
您添加的記錄不再存在蜡歹,因為您使用的是不同的 UserDefaults
套件。 再次加入Leonardo
涕烧!
將active scheme
更改為WidgetExtention
月而。 構(gòu)建并運行。
您現(xiàn)在可以看到widget
顯示添加的記錄议纯。 恭喜父款!
在下一部分中,您將探索 Xcode 中的構(gòu)建設置瞻凤。
Demystifying Build Settings and Build Configurations in Xcode
在本節(jié)中憨攒,您將看到 Xcode
如何顯示和解析構(gòu)建設置。 打開項目編輯器阀参。 找到TARGETS
列表肝集。 選擇 NinjaCounter
作為app target
。
選擇Build Settings
選項卡蛛壳。 選擇 All
和 Levels
構(gòu)建設置過濾器選項杏瞻。
在這里所刀,您可以看到app target
的構(gòu)建設置。 構(gòu)建設置分為四列伐憾,顯示不同范圍內(nèi)的設置值勉痴。
- Resolved:解析優(yōu)先級后的實際值。
-
NinjaCounter (target):顯示在
target
級別設置的值树肃。target
構(gòu)建設置的優(yōu)先級高于project
的優(yōu)先級蒸矛。 默認情況下,target
從project
構(gòu)建設置繼承值胸嘴。 -
Ninja Counter (project):顯示在
project
的構(gòu)建設置中設置的值雏掠。 常規(guī)構(gòu)建設置在項目project
級別可用,其他僅適用于target
劣像。 - iOS Default:顯示設置的 iOS 默認值乡话。
注意:構(gòu)建設置遵循以下優(yōu)先級,從低到高:
Platform defaults
Project.xcconfig file
Project file build settings
Target .xcconfig file
Target build settings
選擇 WidgetExtension target
耳奕。 查看構(gòu)建設置绑青。
您可以在widget’s target level
看到相同的設置。
Settings
有多個值屋群,每個Build Configuration
一個闸婴。 例如,查看Base SDK
芍躏。 構(gòu)建配置就像一個環(huán)境邪乍。
您可以在項目級別全局定義Build Configurations
。 Xcode
為您創(chuàng)建兩個配置:Debug and Release
对竣。
對于這些環(huán)境庇楞,構(gòu)建設置的默認值是不同的。 例如否纬,Clang Optimization Level
在 Debug
中設置為 None -O0
吕晌,讓您調(diào)試和檢查代碼。 同時临燃,在 Release
中聂使,它默認為 Fastest, Smallest -Os
以實現(xiàn)最大的代碼優(yōu)化和最小的可執(zhí)行文件大小。
現(xiàn)在您已經(jīng)介紹了build settings
谬俄,是時候回顧一下targets and schemes
了。
Understanding Targets and Schemes
target
指定單個產(chǎn)品及其構(gòu)建設置和文件弃理。 目標可以是應用程序溃论、擴展程序、框架痘昌、iMessage 應用程序钥勋、應用程序剪輯等炬转。
創(chuàng)建小widget
時,Xcode 創(chuàng)建了一個新target
算灸。 您為應用程序和widget target
配置了開發(fā)團隊和功能扼劈。
Apple 將 Xcode scheme定義如下:“An Xcode scheme defines a collection of targets to build, a configuration to use when building, and a collection of tests to execute.”
創(chuàng)建一個新target
會自動創(chuàng)建一個與之配套的新scheme
。
要查看此內(nèi)容菲驴,請單擊活動方案荐吵。 單擊Edit Scheme…
。
專業(yè)提示:通過按住
Option
鍵單擊active scheme
赊瞬,直接進入scheme editor
先煎,無需通過菜單。
您將看到scheme editor
:
例如巧涧,WidgetExtention scheme
定義了 Xcode
將如何build, run, test, profile, analyze and archive widget target
薯蝎。 它還定義了要與這些操作一起使用的構(gòu)建配置。
您可以看到 Run
默認為 Debug
配置谤绳,而 Archive
默認為 Release
占锯。 Build Configuration
下拉菜單是您更改所選構(gòu)建配置的地方。
關(guān)閉scheme editor
缩筛。 接下來消略,您將為臨時環(huán)境創(chuàng)建一個新的構(gòu)建配置。
Creating a Staging Environment Configuration
要配置和創(chuàng)建應用程序的測試構(gòu)建歪脏,您需要一個暫存構(gòu)建配置疑俭。
打開Project Editor
并選擇 NinjaCounter PROJECT
。 打開Info
選項卡婿失。
這是您定義構(gòu)建配置的地方钞艇。 它們是全局的,并且在targets
之間共享豪硅。 單擊 +
添加一個新的哩照。
選擇Duplicate “Debug” Configuration
。 將新配置命名為 Staging
懒浮。
您將看到新的Staging
配置飘弧。 選擇 NinjaCounter target
并切換到 Build Settings
選項卡。
這些設置現(xiàn)在具有新構(gòu)建配置的新值砚著。 您從 Debug
復制了build configuration
次伶,因此它們具有相同的值。
現(xiàn)在您已經(jīng)創(chuàng)建了臨時環(huán)境稽穆,是時候添加 .xcconfig
文件了冠王。
Creating Configuration Settings Files
使用 Build Settings
選項卡修改設置有一些缺點。 搜索具有不同范圍的長列表非常耗時舌镶,尤其是當您有多個targets
柱彻、build configuration
和設置需要管理時豪娜。 .xcconfig
文件是簡化此過程的替代方法。
在項目導航器中選擇 NinjaCounter
組哟楷。 創(chuàng)建一個新group
瘤载。 命名組為Config Files
。 這是您放置配置文件的地方卖擅。
單擊File ? New ? File…
鸣奔。
在文件模板列表中選擇Configuration Settings File
。
將文件命名為 Debug.xcconfig
磨镶。 對于此應用程序溃蔫,您需要為每個配置創(chuàng)建一個 .xcconfig
文件。 創(chuàng)建 Staging.xcconfig
和 Release.xcconfig
琳猫。
注意:不要將
.xcconfig
文件添加到target memberships
伟叛。 配置設置文件旨在成為開發(fā)依賴項(development dependencies)
。 它們不應包含在app archive
中的資源中脐嫂。
接下來统刮,您將在 Xcode
中設置配置文件。
Working With Configuration Settings Files
要使用配置文件账千,您需要在 Xcode
中設置它們侥蒙。 在此之前,添加app display name
的設置匀奏。
打開 Debug.xcconfig
鞭衩。 添加下面的設置并保存。
APP_NAME = Ninja Counter
.xcconfig
文件中的設置使用以下語法:SETTING_NAME = VALUE
娃善。
注意:即使字符串值包含空格论衍,也不要像
Ninja Counter
那樣用引號將字符串值括起來。 例外情況是聚磺,包含空格的字符串在string list
中時坯台,字符串列表是以空格分隔的字符串值列表。
打開項目編輯器并選擇 NinjaCounter
項目瘫寝。 單擊Info
選項卡蜒蕾。
Configurations
部分是您設置配置文件的地方。
如您所見焕阿,您可以在project level
以及每個target level
為每個環(huán)境使用配置文件咪啡。
在Based on Configuration File
下,單擊配置文件選項暮屡。
Xcode
會顯示您創(chuàng)建的 .xcconfig
文件列表瑟匆。 將每個構(gòu)建配置對應的配置文件設置為app and widget targets
,如下圖:
-
Debug
NinjaCounter: Debug
WidgetExtension: Debug
-
Staging
NinjaCounter: Staging
WidgetExtension: Staging
-
Release
NinjaCounter: Release
WidgetExtension: Release
此時,您已經(jīng)為每個環(huán)境創(chuàng)建了一個配置文件愁溜。 做得好! 接下來外厂,您將為每個環(huán)境自定義設置冕象。
1. Creating a User-Defined Setting to Change the Bundle Display Name
作為開發(fā)人員,您可以在應用的所有階段使用和使用您的應用汁蝶。 當您在不同版本之間切換時渐扮,了解您當前安裝的是哪個版本可能會令人困惑。 因此掖棉,使用不同的display names
很有用墓律。
打開 Debug.xcconfig
。 將 APP_NAME
的值更改為 Ninja CounterDev
幔亥。 這是您在安裝調(diào)試版本時將看到的應用程序顯示名稱耻讽。
現(xiàn)在,您一目了然就知道這是您正在使用絕密和下一代功能進行的開發(fā)版本帕棉!
接下來针肥,您需要更改其他配置的名稱。 打開 Staging.xcconfig
并添加以下行:
APP_NAME = Ninja CounterQA
最后香伴,打開 Release.xcconfig
并使用生產(chǎn)display name
更新設置:
APP_NAME = Ninja Counter
接下來慰枕,在Project navigator
中選擇項目本身。 選擇 NinjaCounter
應用程序target
即纲。
打開Build Settings
選項卡具帮。 滾動到列表末尾。
現(xiàn)在低斋,您可以看到用戶定義的構(gòu)建設置 APP_NAME
和顯示配置文件級別值的新設置范圍蜂厅。 如果您在這里看到您在配置文件中設置的值,那么您就走對了拔稳!
更改應用程序display name
的最后一步是將 Bundle display name
設置為引用您的用戶定義設置葛峻。
打開 NinjaCounter
的 Info.plist
。 添加Bundle display name
屬性巴比。 將該屬性的值設置為 $(APP_NAME)
术奖。
或者,您也可以從Project Editor
的Info
選項卡中添加它轻绞。
確保將 NinjaCounter
設置為active scheme
采记。
構(gòu)建并運行。 按 Shift-Command-H
進入主屏幕政勃。
現(xiàn)在唧龄,您可以看到您的開發(fā)構(gòu)建應用程序名稱。
是時候在 Staging
環(huán)境中測試應用程序了奸远。 按住 Option
鍵并單擊 Xcode
任務欄中的運行按鈕既棺。
接下來讽挟,選擇 Run
操作,然后選擇 Info
選項卡丸冕,然后單擊 Build Configuration
下拉菜單耽梅。 您的新staging configuration
在列表中。 選擇Staging
作為構(gòu)建配置胖烛。
單擊Run
眼姐,等待應用程序啟動,然后返回 iOS 主屏幕佩番。
應用程序顯示名稱現(xiàn)在是 NinjaCounterQA
众旗,可立即顯示您正在使用的構(gòu)建版本。
接下來,您將創(chuàng)建一個基本配置文件以避免冗余值。
2. Retaining Values With Inheritance
在您的配置文件中臭觉,您將不同構(gòu)建的 APP_NAME
設置為 Ninja CounterDev哼御、Ninja CounterQA 和 Ninja Counter
。 release build
名稱 NinjaCounter
是基本值,您可以在每個名稱中重復該值。
在project level
設置常規(guī)構(gòu)建設置是最佳實踐。 然后哗咆,在不同的配置中重復使用這些設置以避免冗余。 在這種情況下益眉,您將在每個構(gòu)建配置中更改 APP_NAME
以從基本值繼承晌柬。
右鍵單擊Config files group
。 選擇New file…
郭脂。 創(chuàng)建一個名為 Base.xcconfig
的新配置文件并添加以下行:
APP_NAME = Ninja Counter
接下來年碘,替換其他配置文件的內(nèi)容如下。
Debug.xcconfig:
#include "Base.xcconfig"
APP_NAME = $(inherited)Dev
Staging.xcconfig:
#include "Base.xcconfig"
APP_NAME = $(inherited)QA
Release.xcconfig:
#include "Base.xcconfig"
在這里展鸡,您更改了三個配置文件以從 Base.xcconfig
繼承和重用基本設置屿衅。 您通過使用 $(inherited)
并附加特定于每個構(gòu)建的名稱部分來完成此操作。
注意:
$(inherited)
值是從包含的文件中引用的(如果有)莹弊,并遵循前面提到的優(yōu)先級涤久。 同樣,如果您在配置文件中繼承系統(tǒng)構(gòu)建設置忍弛,則將根據(jù)優(yōu)先級設置解析值响迂。
最后,在 Staging
中構(gòu)建并運行應用程序细疚。
應用名稱顯示正確蔗彤。 請注意,您不需要將 APP_NAME
定義添加到 Release.xcconfig
。 那是因為設置會回退到繼承的值然遏。
要查看設置在 Xcode
中的顯示方式贫途,請打開Project Editor
。 選擇 NinjaCounter target
啦鸣,然后選擇Build Settings
潮饱。 滾動到User-defined
部分。
盡管在應用程序運行時顯示正確诫给,但解析的值看起來并不正確。 這是因為 Base.xcconfig
未在Project Editor
的Configurations
部分中設置啦扬。 但是中狂,繼承在運行時按預期解析。
要解決此問題扑毡,請在項目編輯器中選擇項目胃榕。 在Configurations
下,在所有三個配置的項目級別設置 Base.xcconfig
瞄摊。
現(xiàn)在勋又,返回app target
的Build Settings
。
這些值現(xiàn)在在 Xcode
中正確顯示换帜。 請注意楔壤,新范圍顯示了項目級配置文件。
接下來惯驼,您將添加更多自定義設置蹲嚣。
3. Referencing Values of Other Settings
現(xiàn)在您的環(huán)境已準備就緒,是時候添加更多設置了祟牲。 將以下內(nèi)容添加到 Base.xcconfig
隙畜。 請務必替換您的bundle identifier
:
BASE_BUNDLE_IDENTIFIER = <your bundle identifier>
PRODUCT_BUNDLE_IDENTIFIER = $(BASE_BUNDLE_IDENTIFIER)
BASE_BUNDLE_IDENTIFIER
是包含項目基本bundle identifier
的用戶定義設置,而 PRODUCT_BUNDLE_IDENTIFIER
是指定bundle identifier
的 Xcode
構(gòu)建設置说贝。
在這里议惰,您引用了 BASE_BUNDLE_IDENTIFIER
的值。 參考語法為:$(OTHER_BUILD_SETTING_NAME)乡恕。
注意:當您從
Info.plist
或.entitlements
文件中引用構(gòu)建設置時言询,您使用相同的引用語法。
現(xiàn)在几颜,如果您要更改 Base.xcconfig
中 BASE_BUNDLE_IDENTIFIER
的值倍试,您將看不到構(gòu)建設置中反映的更改。 那是因為bundle identifier
目前在target’s settings
中是硬編碼的蛋哭。 要解決此問題县习,請返回到Project Editor
并選擇NinjaCounter target
。 在搜索字段中,輸入 bundle
以縮小設置顯示的數(shù)量躁愿。 雙擊target build setting
并將其值更改為:
$(inherited)
之前叛本,您將 UserDefaultsHelper.swift
中的代碼更改為使用app group identifier
作為 UserDefaults
套件名稱,如下所示彤钟。
UserDefaults(suiteName: "group.<your bundle identifier>")
為了避免像套件名稱這樣的硬編碼值来候,請在 Base.xcconfig
中的 PRODUCT_BUNDLE_IDENTIFIER
下添加以下設置:
USER_DEFAULTS_SUITE_NAME = group.$(BASE_BUNDLE_IDENTIFIER)
由于 NinjaCounter
中的app group identifier
取決于bundle identifier
,因此您創(chuàng)建了 USER_DEFAULTS_SUITE_NAME
逸雹。 它內(nèi)聯(lián)引用 BASE_BUNDLE_IDENTIFIER
并附加group.
前綴营搅。 稍后,您將更新您的代碼以使用此新設置梆砸,但首先您必須更新應用程序以使用該設置转质。 在項目導航器中,您將找到兩個 .entitlements
文件帖世。 打開 WidgetExtension.entitlements
并單擊disclosure arrow
以打開設置休蟹。 將 Item 0
的值更改為:
$(USER_DEFAULTS_SUITE_NAME)
接下來,打開 NinjaCounter.entitlements
并執(zhí)行相同的操作日矫。
您通過引用其他設置的值來確保依賴于其他設置的構(gòu)建設置的一致性赂弓。 接下來,您將在代碼中使用該設置并刪除硬編碼的設置哪轿。
4. Accessing Settings From Code
要從代碼訪問構(gòu)建設置盈魁,您首先需要在 Info.plist
中添加一個引用屬性。 打開 NinjaCounter
的 Info.plist
并添加一個名為的自定義屬性:
USER_DEFAULTS_SUITE_NAME
使用下面的值:
$(USER_DEFAULTS_SUITE_NAME)
對widget
的 Info.plist
執(zhí)行相同操作缔逛,因為widget
也需要訪問設置备埃。
接下來,在 NinjaCounter
組中創(chuàng)建一個新的 Swift
文件并將其命名為 Config.swift
褐奴。 打開文件并添加以下代碼:
enum Config {
static func stringValue(forKey key: String) -> String {
guard let value = Bundle.main.object(forInfoDictionaryKey: key) as? String
else {
fatalError("Invalid value or undefined key")
}
return value
}
}
stringValue(forKey:)
是一種輔助方法按脚,可簡化從 Info.plist
檢索值的過程。 它調(diào)用 Bundle
的 object(forInfoDictionaryKey:)
來獲取字符串值敦冬。
注意:您可以從屬性列表中存儲和獲取其他數(shù)據(jù)類型辅搬,例如布爾值和數(shù)組。 為簡單起見脖旱,由于
NinjaCounter
只需要字符串值堪遂,因此此輔助方法僅適用于字符串。
然后萌庆,在文件檢查器中溶褪,除了 NinjaCounter
之外,還選擇 WidgetExtension
作為target
践险。
打開 UserDefaultsHelper.swift
并再次將defaults
聲明替換為:
static private let defaults = UserDefaults(
suiteName: Config.stringValue(forKey: "USER_DEFAULTS_SUITE_NAME"))
?? .standard
在這里猿妈,您更改了 UserDefaultsHelper
的代碼以從構(gòu)建設置中獲取套件名稱吹菱。 您使用了 Config
的方法 stringValue(forKey:)
來獲取值。
接下來彭则,您將添加條件設置鳍刷。
5. Adding Conditions
您可以添加條件來構(gòu)建設置以針對特定的 SDK, architecture
或build configuration
的target
。 在添加不特定于target
的project
范圍設置時俯抖,這尤其有用输瓜。
在 Base.xcconfig
中,添加以下行:
ONLY_ACTIVE_ARCH[config=Debug][sdk=*][arch=*] = YES
在這里芬萍,當應用程序在Debug configuration
中構(gòu)建時尤揣,您將 ONLY_ACTIVE_ARCH
設置為 YES
。 因此柬祠,它通過僅構(gòu)建active architecture
來加快構(gòu)建時間芹缔。
條件設置遵循以下語法:
BUILD_SETTING_NAME[條件=值] = VALUE
將條件值設置為星號意味著任何值。 您在上面添加的設置適用于任何 sdk
和任何architecture
瓶盛,但僅適用于Debug configuration
。
在下一部分中示罗,您將自定義應用程序在不同環(huán)境中的行為惩猫。
Creating Record Stores for Each Environment
現(xiàn)在您的環(huán)境已準備就緒,您將孵化器的記錄存儲在不同的 UserDefaults
鍵中 —— 每個環(huán)境一個蚜点。 由于應用在本地存儲數(shù)據(jù)轧房,這里的 UserDefaults
是應用的“back end”
。
是時候在環(huán)境的配置文件中添加 UserDefaults
鍵了绍绘。
在 Debug.xcconfig
中奶镶,添加:
USER_DEFAULTS_RECORDS_KEY = HatchlingsRecords-Debug
在 Staging.xcconfig
中,添加:
USER_DEFAULTS_RECORDS_KEY = HatchlingsRecords-Staging
在 Release.xcconfig
中陪拘,添加:
USER_DEFAULTS_RECORDS_KEY = HatchlingsRecords
密鑰名稱在每個環(huán)境中都會發(fā)生變化厂镇。
接下來,將以下屬性添加到 NinjaCounter
和擴展的 Info.plist
中左刽。
Key
:
USER_DEFAULTS_RECORDS_KEY
Value
:
$(USER_DEFAULTS_RECORDS_KEY)
之后捺信,打開 UserDefaultsHelper.swift
并將recordsKey
的聲明替換為:
static private let recordsKey = Config
.stringValue(forKey: "USER_DEFAULTS_RECORDS_KEY")
正如您從構(gòu)建設置中獲得 UserDefaults
套件名稱一樣,在上面的更改中欠痴,您使用 stringValue(forKey:)
將硬編碼的 UserDefaults
鍵替換為相應的構(gòu)建設置值迄靠。
最后,您已準備好測試您的更改喇辽! 將active scheme
的Build Configuration
更改為Debug
掌挚。
構(gòu)建并運行。 添加Donatello
記錄菩咨。
接下來吠式,將Build Configuration
更改為Release
陡厘。 構(gòu)建并運行。
您看不到 Donatello
的記錄奇徒,因為您將其存儲在 Debug
存儲區(qū)中雏亚。 將Build Configuration
更改回Debug
。 構(gòu)建并運行摩钙。
您在使用debug build configuration
運行時存儲的記錄就在那里罢低。 現(xiàn)在,您知道您的環(huán)境按預期工作胖笛。
這是否讓您想起了不同的方法网持? 看看下面的代碼。
#if DEBUG
let recordsKey = "HatchlingsRecords-Debug"
#elseif STAGING
let recordsKey = "HatchlingsRecords-Staging"
#else
let recordsKey = "HatchlingsRecords"
#endif
條件編譯是一種流行的做法长踊。 但是功舀,使用它來管理跨環(huán)境的常量有一個缺點,即您將可配置的常量與代碼混合在一起身弊。 使用build settings
來存儲這些值并在代碼中使用它們是一個不錯的選擇辟汰。
那很簡單! 在配置文件中設置設置不僅可以簡化構(gòu)建設置的管理阱佛,還可以讓您從 Xcode
外部化設置帖汞。 這使它們具有可移植性,并使跟蹤源代碼管理中的更改更加方便凑术。
在下一部分中翩蘸,您將為每個target
創(chuàng)建配置文件。
Using Configuration Files for Each Target
該應用程序現(xiàn)在在所有三種環(huán)境中都可以正常運行淮逊。 但是催首,如果您需要為 WidgetExtention
創(chuàng)建或外部化target-specific
的構(gòu)建設置怎么辦? 接下來泄鹏,您將看到如何為widget target
創(chuàng)建配置文件郎任。
在Config files group
中,創(chuàng)建以下配置文件:
- WidgetBase.xcconfig:
#include "Base.xcconfig"
PRODUCT_BUNDLE_IDENTIFIER = $(BASE_BUNDLE_IDENTIFIER).widget
- WidgetDebug.xcconfig:
#include "Debug.xcconfig"
#include "WidgetBase.xcconfig"
- WidgetStaging.xcconfig:
#include "Staging.xcconfig"
#include "WidgetBase.xcconfig"
- WidgetRelease.xcconfig:
#include "Release.xcconfig"
#include "WidgetBase.xcconfig"
在這里命满,您通過將 BASE_BUNDLE_IDENTIFIER
附加到您的基本設置來設置widget
PRODUCT_BUNDLE_IDENTIFIER
涝滴。
接下來,在Project Editor
中為 WidgetExtension target
將文件設置為各自的環(huán)境胶台,如下所示歼疮。
-
Debug
Project: Base
NinjaCounter: Debug
WidgetExtension: WidgetDebug
-
Staging
Project: Base
NinjaCounter: Staging
WidgetExtension: WidgetStaging
-
Release
Project: Base
NinjaCounter: Release
WidgetExtension: WidgetRelease
注意:您不需要設置
WidgetBase.xcconfig
,因為其他文件都包含它诈唬。
最后韩脏,返回到 Project Editor
并將 WidgetExtension target
的 Product Bundle Extension
設置更改為:
$(inherited)
之后,將active scheme
更改為 WidgetExtension
铸磅。 確保構(gòu)建配置為Debug
赡矢。 構(gòu)建并運行杭朱。
該widget
現(xiàn)在顯示您為 Donatello
添加的最新記錄。 盡管 WidgetDebug.xcconfig
不包含任何設置吹散,但它包含來自 WidgetBase.xcconfig
和 Debug.xcconfig
的設置弧械。 這就是當您為widget
設置 Debug.xcconfig
時它起作用的原因。
Differentiating the App Icon for Non-Release Builds
一些利益相關(guān)者空民,如測試人員和 QA 工程師刃唐,使用多個版本的應用程序。 例如界轩,他們可能會使用 App Store
版本和開發(fā)人員或 TestFlight
提供的 Staging
版本画饥。 為了讓您同事的生活更輕松,您的下一步將是更改應用程序圖標浊猾,以區(qū)分 Debug
和 Staging
版本與 Release
版本抖甘。
在項目中,您將在應用程序的 Assets.xcassets
中找到另一個名為 AppIcon-NonProd
的應用程序圖標集葫慎。
設置資產(chǎn)目錄應用圖標集的名稱衔彻,需要修改配置文件中的ASSETCATALOG_COMPILER_APPICON_NAME
。
在 Debug.xcconfig
和 Staging.xcconfig
中偷办,添加:
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-NonProd
在Release.xcconfig
中米奸,添加:
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
注意:正如您在
Project Editor
的Build Settings
選項卡和Info.plist
中看到的,有許多構(gòu)建設置爽篷。 你不必記住每個的名字。 相反慢睡,請使用 Apple 文檔中的build settings reference逐工。
將active scheme
設置為 NinjaCounter
。 將Build Configuration
設置為Debug
漂辐。 構(gòu)建并運行泪喊。 進入主屏幕。
圖標沒有改變髓涯,因為Target Build Settings
具有更高的優(yōu)先級袒啼。 要解決此問題,請從項目編輯器轉(zhuǎn)到 NinjaCounter target
的Build Settings
纬纪,然后找到Asset Catalog App Icon Set Name
蚓再。
在配置文件的范圍內(nèi),您可以看到添加到配置文件中的值包各。 但是摘仅,該設置解析為target scope
內(nèi)的值。
要解決此問題问畅,請將app target
范圍的父值更改為 $(inherited)
娃属。
解析的值現(xiàn)在與配置文件匹配六荒。
構(gòu)建并運行。 進入主屏幕矾端。
該應用程序現(xiàn)在顯示 AppIcon-NonProd
應用程序圖標集中的圖標掏击。
注意:在
widget
的資產(chǎn)目錄中,有一個名為AppIcon-NonProd
的空應用圖標集秩铆。雖然它沒有被使用砚亭,但它解決了編譯時錯誤,Xcode
會警告widget
的資產(chǎn)目錄中不存在AppIcon-NonProd
豺旬。這是因為widget target
從app target
繼承ASSETCATALOG_COMPILER_APPICON_NAME
钠惩,Xcode
將在編譯時檢查該值。
在本教程中族阅,您使用 .xcconfig
文件來外部化構(gòu)建設置篓跛。你涵蓋:
- 跨不同
build configurations
管理設置。 - 針對不同環(huán)境和
targets
使用配置文件的多種方法坦刀。 - 從代碼訪問構(gòu)建設置愧沟。
有關(guān)build configuration and app distribution best practices
的更多信息,請查看我們iOS App Distribution & Best Practices一書鲤遥。
以下是 Apple
文檔中的一些更有用的資源:
后記
本篇主要講述了使用
Build Configurations
和.xcconfig
構(gòu)建你的App
沐寺,感興趣的給個贊或者關(guān)注~~~