一个简单的 Swift 包管理器框架,可从环境变量和应用程序键值文件生成 Swift 原生代码。
您可以自动生成一个 Swift 类文件,该文件管理位于项目根目录中的“.env”或“.env.json”文件的键值。 这可以通过 Swift 包管理器的插件功能来实现,使其非常容易集成到应用程序中。
管理自动生成的键值的类会写入 Derived Data 中。 这降低了意外提交管理敏感信息的类以及正在开发的应用程序代码的风险。
使用 Swift Package Manager:File > Swift Packages > Add Package Dependency 添加 https://github.com/MasamiYamate/SwiftPackageKeys 选择 “Up to Next Major” 和 “1.0.0”
务必执行此操作。 为了防止 Git 跟踪“.env”或“.env.json”文件并阻止将其提交到存储库,请将 “ .env” 和/或 “.env.json” 添加到 “.gitignore” 文件。
.env
.env.json
.env 和 .env.json 文件不包含在存储库中,因此有必要考虑如何共享它们。 建议使用 OpenSSL 等工具加密 .env 或 .env.json 文件,并将加密后的文件传递给应用程序存储库。 一种常见的方法是在团队内共享使用的加密密码,在开发或 CI 环境中解密加密的 .env 或 .env.json 文件,并使用它。
在项目的根目录中创建一个 .env 或 .env.json 文件。
$ touch .env
或
$ touch .env.json
以键值对的形式将要管理的 API 密钥添加到 .env 文件中。
APIKEY_DEV=abcdefg123456
apiKeyProd=abcdefg654321
使用蛇形命名或驼峰命名都没有关系。 转换为 Swift 原生代码时,键名会自动转换为蛇形命名。 此外,不要将 Key 和 Value 都用双引号引起来。
如果使用 .env.json,请包含以下内容。
{
"keys": [
{
"key": "KEY_NAME",
"productionValue": "production_key_value",
"stagingValue": "staging_key_value",
"debugValue": "debug_key_value"
},
{
"key": "keyName2",
"productionValue": "production_key_value2",
"stagingValue": "staging_key_value2",
"debugValue": "debug_key_value2"
},
{
"key": "key_Name3",
"productionValue": "production_key_value3",
"stagingValue": "staging_key_value3",
"debugValue": "debug_key_value3"
}
]
}
使用 .env.json 时,除了生产和调试环境之外,还可以定义用于暂存环境的配置值。
在使用 Framework 之前,请先构建一次应用。 Xcode 可能会显示下图中的警报。 在这种情况下,请选择“Trust & Enable All”。
如果要在您的应用程序中使用此框架,您需要首先在要使用的类中导入它。 从 .env 或 .env.json 获取的值可以通过从 SwiftPackageKeys 类获取环境变量的结构,然后检索特定键和环境的值来访问。
import Foundation
import SwiftPackageKeys // << import framework
final class KeyManager {
// Structure for Configuration Values
let keyObject = SwiftPackageKeys.keyName
// Key
var key: String {
return keyObject.key
}
// value
// - note: If only production environment values are set, those values will be used.
// If both production and debug environment values are set, the appropriate environment variables will be used based on the app's Debug/Release flags.
var value: String? {
return keyObject.value
}
// production
var productionValue: String? {
return keyObject.fetchValue(stage: .production)
}
// staging
var stagingValue: String? {
return keyObject.fetchValue(stage: .staging)
}
// debug
var debugValue: String? {
return keyObject.fetchValue(stage: .debug)
}
}
在此插件中,为了更难以通过逆向工程获取机密信息,我们使用可逆加密进行混淆。 之后,插件会生成代码以引用可以在 Swift 中处理的环境变量。
我们采用了 XOR 加密进行可逆加密。 对于 XOR 加密,我们使用为每次构建随机生成的加密密钥。 由于我们不使用固定值的加密密钥,即使从 IPA 文件执行逆向工程,在获取加密密钥后,也需要进行分析。 这使得分析比使用固定值的加密密钥进行加密和混淆更困难。
但是,由于 XOR 加密是可逆的,并且加密密钥也嵌入在二进制文件中,因此可以通过分析来获取机密信息。 请理解并使用它,我们只是混淆机密信息,使其更难以通过逆向工程获得。