版本记录
版本号 | 时间 |
---|---|
V1.0 | 2021.06.09 星期三 |
前言
程序总会有bug,如果有好的调试技巧和方法,那么就是事半功倍,这个专题专门和大家分享下和调试相关的技巧。希望可以帮助到大家。感兴趣的可以看下面几篇文章。
1. 程序调试 (一) —— App Crash的调试和解决示例(一)
2. 程序调试 (二) —— Xcode Simulator的高级功能(一)
3. 程序调试 (三) —— Xcode Simulator的高级功能(二)
4. 程序调试 (四) —— Xcode内存管理(一)
开始
首先看下主要内容:
使用
Xcode build settings
和.xcconfig
文件以不同的构建配置(build configurations)
更改应用程序的设置和图标。内容来自翻译。
下面看下写作环境:
Swift 5, iOS 14, Xcode 12
下面就是正文啦。
Debug, test, release
—— 这些是大多数应用程序经历的阶段。 在每个阶段,应用程序都有不同的构建设置、定义和常量。 开发人员使用debug
后端 URL 和设置构建应用程序。 测试人员使用类似生产的设置测试 beta
版本。 客户使用具有最终生产设置的应用程序。
在 Xcode
中跨不同环境管理这些设置非常耗时——更不用说当您有多个targets
时增加的工作了。 幸运的是,Apple 提供了一种更好的方式来处理这些设置:Xcode build configuration files, or .xcconfig files。
在本教程中,您将:
- 使用
Xcode
构建配置文件。 - 管理跨多个环境和
targets
的构建设置。 - 从代码访问构建设置。
打开起始项目。 构建并运行。
您将使用的应用程序 NinjaCounter 可帮助生物学家和爱好者计算海龟孵化的数量。 该应用程序有一个视图:CounterView.swift
,用户可以在其中记录幼龟。
在 NinjaCounter
组中,您会发现以下内容:
- Hatchling:一个简单的结构,具有孵化记录属性。
-
UserDefaultsHelper:一个
UserDefaults
助手,提供存储和加载孵化记录的方法。
构建并运行。 在tag text field
中,输入 Leonardo
。 点击+ Hatchling
按钮。
这样,您就创建了一个带有孵化标签和孵化时间的新记录。
现在您已经了解了入门项目的要点,您将设置app widget
。
Setting Up Widget with App Group
打开 Widget.swift
并查看代码。 它创建了一个简单的widget
,显示计数的孵化数量和报告的最后一个孵化的标签。
在 getTimeline(in:completion:)
中,widget
使用 UserDefaultsHelper
的 getRecordsCount()
和 getRecords()
从 UserDefaults
获取数据。
选择 WidgetExtension scheme
。 构建并运行。
目前,即使您刚刚录制了 Leonardo
,该widget
也不显示任何数据。 这是因为扩展程序无权访问应用程序的 UserDefaults
。 要解决此问题,您需要将应用程序和小部件添加到app group
。
在项目导航器中选择 NinjaCounter
项目以显示Project Editor
。 选择 NinjaCounter target
。 打开Signing & Capabilities
选项卡。
选择development team
进行签名。
将Bundle Identifier
更改为您独有的内容,例如 com.myorg.NinjaCounter
。 请记住这一点,因为您将再次需要它。
单击+ Capability
。 双击App Groups
。
现在您已将App Groups
添加到capabilities
中,单击 +
按钮创建app group
。 您将看到输入组名称的提示。
输入group
,单击OK
。
现在,对 Widget Extension target
执行相同的步骤。 确保bundle identifier
以 .widget
结尾,但使用您为主应用程序创建的相同app group
。 这允许在主机应用程序和widget extension
之间共享数据。
现在您已经创建了App Group
并将targets
添加到其中,是时候让应用程序组访问 UserDefaults
套件了。
打开 UserDefaultsHelper.swift
并将defaults
声明替换为:
static private let defaults = UserDefaults(
suiteName: "<#the app group name you defined#>")
?? .standard
使用此代码,您可以确保应用从app group
共享的 UserDefaults
套件中保存和读取数据。 这允许widget
访问孵化数据。
将active scheme
更改为 NinjaCounter
。 构建并运行。
您添加的记录不再存在,因为您使用的是不同的 UserDefaults
套件。 再次加入Leonardo
!
将active scheme
更改为WidgetExtention
。 构建并运行。
您现在可以看到widget
显示添加的记录。 恭喜!
在下一部分中,您将探索 Xcode 中的构建设置。
Demystifying Build Settings and Build Configurations in Xcode
在本节中,您将看到 Xcode
如何显示和解析构建设置。 打开项目编辑器。 找到TARGETS
列表。 选择 NinjaCounter
作为app target
。
选择Build Settings
选项卡。 选择 All
和 Levels
构建设置过滤器选项。
在这里,您可以看到app target
的构建设置。 构建设置分为四列,显示不同范围内的设置值。
- Resolved:解析优先级后的实际值。
-
NinjaCounter (target):显示在
target
级别设置的值。target
构建设置的优先级高于project
的优先级。 默认情况下,target
从project
构建设置继承值。 -
Ninja Counter (project):显示在
project
的构建设置中设置的值。 常规构建设置在项目project
级别可用,其他仅适用于target
。 - iOS Default:显示设置的 iOS 默认值。
注意:构建设置遵循以下优先级,从低到高:
Platform defaults
Project.xcconfig file
Project file build settings
Target .xcconfig file
Target build settings
选择 WidgetExtension target
。 查看构建设置。
您可以在widget’s target level
看到相同的设置。
Settings
有多个值,每个Build Configuration
一个。 例如,查看Base SDK
。 构建配置就像一个环境。
您可以在项目级别全局定义Build Configurations
。 Xcode
为您创建两个配置:Debug and Release
。
对于这些环境,构建设置的默认值是不同的。 例如,Clang Optimization Level
在 Debug
中设置为 None -O0
,让您调试和检查代码。 同时,在 Release
中,它默认为 Fastest, Smallest -Os
以实现最大的代码优化和最小的可执行文件大小。
现在您已经介绍了build settings
,是时候回顾一下targets and schemes
了。
Understanding Targets and Schemes
target
指定单个产品及其构建设置和文件。 目标可以是应用程序、扩展程序、框架、iMessage 应用程序、应用程序剪辑等。
创建小widget
时,Xcode 创建了一个新target
。 您为应用程序和widget target
配置了开发团队和功能。
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.”
创建一个新target
会自动创建一个与之配套的新scheme
。
要查看此内容,请单击活动方案。 单击Edit Scheme…
。
专业提示:通过按住
Option
键单击active scheme
,直接进入scheme editor
,无需通过菜单。
您将看到scheme editor
:
例如,WidgetExtention scheme
定义了 Xcode
将如何build, run, test, profile, analyze and archive widget target
。 它还定义了要与这些操作一起使用的构建配置。
您可以看到 Run
默认为 Debug
配置,而 Archive
默认为 Release
。 Build Configuration
下拉菜单是您更改所选构建配置的地方。
关闭scheme editor
。 接下来,您将为临时环境创建一个新的构建配置。
Creating a Staging Environment Configuration
要配置和创建应用程序的测试构建,您需要一个暂存构建配置。
打开Project Editor
并选择 NinjaCounter PROJECT
。 打开Info
选项卡。
这是您定义构建配置的地方。 它们是全局的,并且在targets
之间共享。 单击 +
添加一个新的。
选择Duplicate “Debug” Configuration
。 将新配置命名为 Staging
。
您将看到新的Staging
配置。 选择 NinjaCounter target
并切换到 Build Settings
选项卡。
这些设置现在具有新构建配置的新值。 您从 Debug
复制了build configuration
,因此它们具有相同的值。
现在您已经创建了临时环境,是时候添加 .xcconfig
文件了。
Creating Configuration Settings Files
使用 Build Settings
选项卡修改设置有一些缺点。 搜索具有不同范围的长列表非常耗时,尤其是当您有多个targets
、build configuration
和设置需要管理时。 .xcconfig
文件是简化此过程的替代方法。
在项目导航器中选择 NinjaCounter
组。 创建一个新group
。 命名组为Config Files
。 这是您放置配置文件的地方。
单击File ▸ New ▸ File…
。
在文件模板列表中选择Configuration Settings File
。
将文件命名为 Debug.xcconfig
。 对于此应用程序,您需要为每个配置创建一个 .xcconfig
文件。 创建 Staging.xcconfig
和 Release.xcconfig
。
注意:不要将
.xcconfig
文件添加到target memberships
。 配置设置文件旨在成为开发依赖项(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
为每个环境使用配置文件。
在Based on Configuration File
下,单击配置文件选项。
Xcode
会显示您创建的 .xcconfig
文件列表。 将每个构建配置对应的配置文件设置为app and widget targets
,如下图:
-
Debug
NinjaCounter: Debug
WidgetExtension: Debug
-
Staging
NinjaCounter: Staging
WidgetExtension: Staging
-
Release
NinjaCounter: Release
WidgetExtension: Release
此时,您已经为每个环境创建了一个配置文件。 做得好! 接下来,您将为每个环境自定义设置。
1. Creating a User-Defined Setting to Change the Bundle Display Name
作为开发人员,您可以在应用的所有阶段使用和使用您的应用。 当您在不同版本之间切换时,了解您当前安装的是哪个版本可能会令人困惑。 因此,使用不同的display names
很有用。
打开 Debug.xcconfig
。 将 APP_NAME
的值更改为 Ninja CounterDev
。 这是您在安装调试版本时将看到的应用程序显示名称。
现在,您一目了然就知道这是您正在使用绝密和下一代功能进行的开发版本!
接下来,您需要更改其他配置的名称。 打开 Staging.xcconfig
并添加以下行:
APP_NAME = Ninja CounterQA
最后,打开 Release.xcconfig
并使用生产display name
更新设置:
APP_NAME = Ninja Counter
接下来,在Project navigator
中选择项目本身。 选择 NinjaCounter
应用程序target
。
打开Build Settings
选项卡。 滚动到列表末尾。
现在,您可以看到用户定义的构建设置 APP_NAME
和显示配置文件级别值的新设置范围。 如果您在这里看到您在配置文件中设置的值,那么您就走对了!
更改应用程序display name
的最后一步是将 Bundle display name
设置为引用您的用户定义设置。
打开 NinjaCounter
的 Info.plist
。 添加Bundle display name
属性。 将该属性的值设置为 $(APP_NAME)
。
或者,您也可以从Project Editor
的Info
选项卡中添加它。
确保将 NinjaCounter
设置为active scheme
。
构建并运行。 按 Shift-Command-H
进入主屏幕。
现在,您可以看到您的开发构建应用程序名称。
是时候在 Staging
环境中测试应用程序了。 按住 Option
键并单击 Xcode
任务栏中的运行按钮。
接下来,选择 Run
操作,然后选择 Info
选项卡,然后单击 Build Configuration
下拉菜单。 您的新staging configuration
在列表中。 选择Staging
作为构建配置。
单击Run
,等待应用程序启动,然后返回 iOS 主屏幕。
应用程序显示名称现在是 NinjaCounterQA
,可立即显示您正在使用的构建版本。
接下来,您将创建一个基本配置文件以避免冗余值。
2. Retaining Values With Inheritance
在您的配置文件中,您将不同构建的 APP_NAME
设置为 Ninja CounterDev、Ninja CounterQA 和 Ninja Counter
。 release build
名称 NinjaCounter
是基本值,您可以在每个名称中重复该值。
在project level
设置常规构建设置是最佳实践。 然后,在不同的配置中重复使用这些设置以避免冗余。 在这种情况下,您将在每个构建配置中更改 APP_NAME
以从基本值继承。
右键单击Config files group
。 选择New file…
。 创建一个名为 Base.xcconfig
的新配置文件并添加以下行:
APP_NAME = Ninja Counter
接下来,替换其他配置文件的内容如下。
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)
并附加特定于每个构建的名称部分来完成此操作。
注意:
$(inherited)
值是从包含的文件中引用的(如果有),并遵循前面提到的优先级。 同样,如果您在配置文件中继承系统构建设置,则将根据优先级设置解析值。
最后,在 Staging
中构建并运行应用程序。
应用名称显示正确。 请注意,您不需要将 APP_NAME
定义添加到 Release.xcconfig
。 那是因为设置会回退到继承的值。
要查看设置在 Xcode
中的显示方式,请打开Project Editor
。 选择 NinjaCounter target
,然后选择Build Settings
。 滚动到User-defined
部分。
尽管在应用程序运行时显示正确,但解析的值看起来并不正确。 这是因为 Base.xcconfig
未在Project Editor
的Configurations
部分中设置。 但是,继承在运行时按预期解析。
要解决此问题,请在项目编辑器中选择项目。 在Configurations
下,在所有三个配置的项目级别设置 Base.xcconfig
。
现在,返回app target
的Build Settings
。
这些值现在在 Xcode
中正确显示。 请注意,新范围显示了项目级配置文件。
接下来,您将添加更多自定义设置。
3. Referencing Values of Other Settings
现在您的环境已准备就绪,是时候添加更多设置了。 将以下内容添加到 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
构建设置。
在这里,您引用了 BASE_BUNDLE_IDENTIFIER
的值。 参考语法为:$(OTHER_BUILD_SETTING_NAME)。
注意:当您从
Info.plist
或.entitlements
文件中引用构建设置时,您使用相同的引用语法。
现在,如果您要更改 Base.xcconfig
中 BASE_BUNDLE_IDENTIFIER
的值,您将看不到构建设置中反映的更改。 那是因为bundle identifier
目前在target’s settings
中是硬编码的。 要解决此问题,请返回到Project Editor
并选择NinjaCounter target
。 在搜索字段中,输入 bundle
以缩小设置显示的数量。 双击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
,因此您创建了 USER_DEFAULTS_SUITE_NAME
。 它内联引用 BASE_BUNDLE_IDENTIFIER
并附加group.
前缀。 稍后,您将更新您的代码以使用此新设置,但首先您必须更新应用程序以使用该设置。 在项目导航器中,您将找到两个 .entitlements
文件。 打开 WidgetExtension.entitlements
并单击disclosure arrow
以打开设置。 将 Item 0
的值更改为:
$(USER_DEFAULTS_SUITE_NAME)
接下来,打开 NinjaCounter.entitlements
并执行相同的操作。
您通过引用其他设置的值来确保依赖于其他设置的构建设置的一致性。 接下来,您将在代码中使用该设置并删除硬编码的设置。
4. Accessing Settings From Code
要从代码访问构建设置,您首先需要在 Info.plist
中添加一个引用属性。 打开 NinjaCounter
的 Info.plist
并添加一个名为的自定义属性:
USER_DEFAULTS_SUITE_NAME
使用下面的值:
$(USER_DEFAULTS_SUITE_NAME)
对widget
的 Info.plist
执行相同操作,因为widget
也需要访问设置。
接下来,在 NinjaCounter
组中创建一个新的 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
检索值的过程。 它调用 Bundle
的 object(forInfoDictionaryKey:)
来获取字符串值。
注意:您可以从属性列表中存储和获取其他数据类型,例如布尔值和数组。 为简单起见,由于
NinjaCounter
只需要字符串值,因此此辅助方法仅适用于字符串。
然后,在文件检查器中,除了 NinjaCounter
之外,还选择 WidgetExtension
作为target
。
打开 UserDefaultsHelper.swift
并再次将defaults
声明替换为:
static private let defaults = UserDefaults(
suiteName: Config.stringValue(forKey: "USER_DEFAULTS_SUITE_NAME"))
?? .standard
在这里,您更改了 UserDefaultsHelper
的代码以从构建设置中获取套件名称。 您使用了 Config
的方法 stringValue(forKey:)
来获取值。
接下来,您将添加条件设置。
5. Adding Conditions
您可以添加条件来构建设置以针对特定的 SDK, architecture
或build configuration
的target
。 在添加不特定于target
的project
范围设置时,这尤其有用。
在 Base.xcconfig
中,添加以下行:
ONLY_ACTIVE_ARCH[config=Debug][sdk=*][arch=*] = YES
在这里,当应用程序在Debug configuration
中构建时,您将 ONLY_ACTIVE_ARCH
设置为 YES
。 因此,它通过仅构建active architecture
来加快构建时间。
条件设置遵循以下语法:
BUILD_SETTING_NAME[条件=值] = VALUE
将条件值设置为星号意味着任何值。 您在上面添加的设置适用于任何 sdk
和任何architecture
,但仅适用于Debug configuration
。
在下一部分中,您将自定义应用程序在不同环境中的行为。
Creating Record Stores for Each Environment
现在您的环境已准备就绪,您将孵化器的记录存储在不同的 UserDefaults
键中 —— 每个环境一个。 由于应用在本地存储数据,这里的 UserDefaults
是应用的“back end”
。
是时候在环境的配置文件中添加 UserDefaults
键了。
在 Debug.xcconfig
中,添加:
USER_DEFAULTS_RECORDS_KEY = HatchlingsRecords-Debug
在 Staging.xcconfig
中,添加:
USER_DEFAULTS_RECORDS_KEY = HatchlingsRecords-Staging
在 Release.xcconfig
中,添加:
USER_DEFAULTS_RECORDS_KEY = HatchlingsRecords
密钥名称在每个环境中都会发生变化。
接下来,将以下属性添加到 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")
正如您从构建设置中获得 UserDefaults
套件名称一样,在上面的更改中,您使用 stringValue(forKey:)
将硬编码的 UserDefaults
键替换为相应的构建设置值。
最后,您已准备好测试您的更改! 将active scheme
的Build Configuration
更改为Debug
。
构建并运行。 添加Donatello
记录。
接下来,将Build Configuration
更改为Release
。 构建并运行。
您看不到 Donatello
的记录,因为您将其存储在 Debug
存储区中。 将Build Configuration
更改回Debug
。 构建并运行。
您在使用debug build configuration
运行时存储的记录就在那里。 现在,您知道您的环境按预期工作。
这是否让您想起了不同的方法? 看看下面的代码。
#if DEBUG
let recordsKey = "HatchlingsRecords-Debug"
#elseif STAGING
let recordsKey = "HatchlingsRecords-Staging"
#else
let recordsKey = "HatchlingsRecords"
#endif
条件编译是一种流行的做法。 但是,使用它来管理跨环境的常量有一个缺点,即您将可配置的常量与代码混合在一起。 使用build settings
来存储这些值并在代码中使用它们是一个不错的选择。
那很简单! 在配置文件中设置设置不仅可以简化构建设置的管理,还可以让您从 Xcode
外部化设置。 这使它们具有可移植性,并使跟踪源代码管理中的更改更加方便。
在下一部分中,您将为每个target
创建配置文件。
Using Configuration Files for Each Target
该应用程序现在在所有三种环境中都可以正常运行。 但是,如果您需要为 WidgetExtention
创建或外部化target-specific
的构建设置怎么办? 接下来,您将看到如何为widget target
创建配置文件。
在Config files group
中,创建以下配置文件:
- 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
将文件设置为各自的环境,如下所示。
-
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
。 确保构建配置为Debug
。 构建并运行。
该widget
现在显示您为 Donatello
添加的最新记录。 尽管 WidgetDebug.xcconfig
不包含任何设置,但它包含来自 WidgetBase.xcconfig
和 Debug.xcconfig
的设置。 这就是当您为widget
设置 Debug.xcconfig
时它起作用的原因。
Differentiating the App Icon for Non-Release Builds
一些利益相关者,如测试人员和 QA 工程师,使用多个版本的应用程序。 例如,他们可能会使用 App Store
版本和开发人员或 TestFlight
提供的 Staging
版本。 为了让您同事的生活更轻松,您的下一步将是更改应用程序图标,以区分 Debug
和 Staging
版本与 Release
版本。
在项目中,您将在应用程序的 Assets.xcassets
中找到另一个名为 AppIcon-NonProd
的应用程序图标集。
设置资产目录应用图标集的名称,需要修改配置文件中的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
中看到的,有许多构建设置。 你不必记住每个的名字。 相反,请使用 Apple 文档中的build settings reference。
将active scheme
设置为 NinjaCounter
。 将Build Configuration
设置为Debug
。 构建并运行。 进入主屏幕。
图标没有改变,因为Target Build Settings
具有更高的优先级。 要解决此问题,请从项目编辑器转到 NinjaCounter target
的Build Settings
,然后找到Asset Catalog App Icon Set Name
。
在配置文件的范围内,您可以看到添加到配置文件中的值。 但是,该设置解析为target scope
内的值。
要解决此问题,请将app target
范围的父值更改为 $(inherited)
。
解析的值现在与配置文件匹配。
构建并运行。 进入主屏幕。
该应用程序现在显示 AppIcon-NonProd
应用程序图标集中的图标。
注意:在
widget
的资产目录中,有一个名为AppIcon-NonProd
的空应用图标集。虽然它没有被使用,但它解决了编译时错误,Xcode
会警告widget
的资产目录中不存在AppIcon-NonProd
。这是因为widget target
从app target
继承ASSETCATALOG_COMPILER_APPICON_NAME
,Xcode
将在编译时检查该值。
在本教程中,您使用 .xcconfig
文件来外部化构建设置。你涵盖:
- 跨不同
build configurations
管理设置。 - 针对不同环境和
targets
使用配置文件的多种方法。 - 从代码访问构建设置。
有关build configuration and app distribution best practices
的更多信息,请查看我们iOS App Distribution & Best Practices一书。
以下是 Apple
文档中的一些更有用的资源:
后记
本篇主要讲述了使用
Build Configurations
和.xcconfig
构建你的App
,感兴趣的给个赞或者关注~~~