在Objective-C
中,有时使用静态字符串常量来定义备用API密钥(例如,区分分析包的RELEASE和DEBUG密钥,如MixPanel,Flurry或Crashlytics):
#if DEBUG
static NSString *const API_KEY = @"KEY_A";
#else
static NSString *const API_KEY = @"KEY_B";
#endif
然后......
[Analytics startSession:API_KEY];
这是如何转换为Swift的,因为Swift编译器不再使用预处理器?
答案 0 :(得分:115)
更新:Xcode 8现在自动支持,请参阅@ DanLoewenherz上面的回复。
在Xcode 8之前,您仍然可以以相同的方式使用宏:
#if DEBUG
let apiKey = "KEY_A"
#else
let apiKey = "KEY_B"
#endif
但是为了让它们被Swift选中,你需要在目标的Build Settings中设置“Other Swift Flags”:
-D
标志答案 1 :(得分:97)
Apple从Xcode 8开始全面支持Swift预处理程序标志,因此不再需要在“其他Swift标志”中设置这些值。
新设置称为“活动编译条件”,它为Swift等效的预处理程序标志提供顶级支持。你以与“其他Swift标志”完全相同的方式使用它,除了不需要在“-D”之前添加值(所以它只是更清洁一点)。
Active Compilation Conditions
是一个新的构建设置,用于将条件编译标志传递给Swift编译器。此设置的值的每个元素都传递给前缀为-
D的swiftc,就像Preprocessor Macros
的元素传递给具有相同前缀的clang一样。 (22457329)
您可以像这样使用上述设置:
#if DEBUG
let accessToken = "DebugAccessToken"
#else
let accessToken = "ProductionAccessToken"
#endif
答案 2 :(得分:1)
作为后续观察,请尽量不要在存储库中以纯文本形式保留api密钥/秘密。使用秘密管理系统将密钥/秘密加载到用户的环境变量中。否则,如果可以接受,则必须执行步骤1。
../set_keys.sh
列表的export API_KEY_A='<plaintext_key_aef94c5l6>'
(使用单引号防止进行评估)source ../set_keys.sh
的运行脚本阶段并将其移至执行顺序的顶部API_KEY_A="$API_KEY_A"
这会将环境变量捕获到编译器定义中,以后将在每个源文件的每次clang调用中使用该变量。
示例目录结构
[10:33:15] ~/code/memo yes? tree -L 2 .
.
├── Memo
│ ├── Memo
│ ├── Memo.xcodeproj
│ ├── Memo.xcworkspace
│ ├── Podfile
│ ├── Podfile.lock
│ └── Pods
└── keys
答案 3 :(得分:0)
在快速包中,您必须在swiftSettings
文件中.target
的{{1}}参数内执行此操作。使用Package.swift
方法(Apple documentation)或Swift documentation
define
我的看起来像这样并且可以正常工作!
targets: [
.target(name: String,
dependencies: [Target.Dependency],
path: String?,
exclude: [String]?,
sources: [String]?,,
cSettings: [CSetting]?,
cxxSettings: [CXXSetting]?,
swiftSettings: [SwiftSetting]?,
linkerSettings: [LinkerSetting]?),
在我的代码中,我可以使用以下条件进行编译:
swiftSettings: [
.define("VAPOR")
]