iOS 使用 Flutter 构建的 Sourcery

iOS Sourcery with Flutter build

我正在尝试为 iOS 构建我的 flutter 应用程序,它有一个 google 映射密钥,我想保护它而不是签入源代码管理它需要从 azure 构建,以实现我将我的地图密钥作为秘密变量存储在 azure 中,并作为本地系统环境变量,我正在使用 Sourcery https://github.com/krzysztofzablocki/Sourcery 为我生成包含此密钥的 class,一切正常但是只有第二次构建,第一次构建总是失败。

所以我正在使用这个命令进行构建

flutter build ios --flavor dev --verbose

第一个运行会给我错误

 error: Build input file cannot be found:
           '/Users/martin/xxx/xxx/xxx/ios/Runner/Credentials.generated.swift' (in target

'Runner'

然后再次发出相同的命令

** BUILD SUCCEEDED **

这是我的 运行 脚本,它在编译源代码之前和 flutter 运行 脚本之后被调用

这会调用我的脚本,该脚本会调用另一个脚本来导出映射 api 键和 运行s sourcery 命令,使用 .yml 文件作为其配置,这是脚本,(它还进行一些日志记录)

#!/bin/bash

echo "Generate Credentials Code"
CREDENTIALS_DIR="$SRCROOT/credentials"

# Set credentials if local script for adding environment variables exist
if [ -f "$CREDENTIALS_DIR/add_credentials_to_env.sh" ]; then
  echo "Add credentials to environement"
  source "$CREDENTIALS_DIR/add_credentials_to_env.sh"
  echo "finished running add_credentials_to_env.sh"
fi

echo "RUN SOURCERY"

$SRCROOT/Pods/Sourcery/bin/sourcery --config "$SRCROOT/config.yml" 
echo "FINISHED RUNNING SOURCERY"

for file in "$SRCROOT/Runner"/*; do
  echo "$file"
done

这是我的配置文件

sources:
  - .
project:
  file: Runner.xcodeproj
  target:
    name: Runner
    module: Runner
templates:
  - credentials/Credentials.stencil
output:
  path: ./Runner/
  link:
    project: Runner.xcodeproj
    target: Runner

args:
  mapsApiKey: ${MAPS_API_KEY_IOS}

这会在第一次构建时正确生成我的 class,并且似乎已正确添加到目标中(编辑掉我的密钥),但只有当我再次 运行 构建命令时,应用程序才会编译.

// Generated using Sourcery 1.4.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
public struct Credentials {
    let mapsApiKey: String
}
public let credentials = Credentials(mapsApiKey: 
"xxxxxxxxxxMY_KEYxxxxxxxxxxx")

有什么想法吗?

xcode 12.5 m1 macbook pro, swift 5

看来您生成文件的时间太晚了。我建议将您的脚本移动到 Aggregate 并将其添加为目标的依赖项

  1. 添加聚合

  1. 将您的脚本移至 'Run script' 部分

  1. 将 'PreBuildScriptsRunner' 添加为应用程序目标的依赖项,确保 'Dependencies' 部分位于所有其他部分之上

手动设置环境变量是开发人员必须在自己的机器上做的一件烦人的事情,并且有更好/更常见的设置私钥的方法。使用环境变量 / bash 几年后,它仍然会导致不易检测的问题。你可能想要自动化/记录它,但你必须考虑使用 zshfishbash 的开发人员?另外,我尽可能避免使用 Xcode 构建阶段。

解决方案? (这是我的)

为什么不使用 CI(Azure 管道?我使用 Github 工作流程)编写 Xcode 构建配置文件(不是 Swift文件)。敏感密钥可能位于文件 Secrets.xcconfig 中,该文件作为构建配置添加到您的 Xcode 中。然后,在您的 Info.plist 应用程序中,您的代码可以加载它们。

创建一个文件,Secrets.xcconfig:

SECRET_API_KEY = 12312rfiwhvde.wvascafsf.df325

将其添加到您的 Xcode 项目中,然后添加到项目的构建配置中:

Secrets.xcconfig 添加到您的 .gitignore

确保 git 在将文件提交到存储库之前忽略该文件。您还可以保留用户可以使用的 Example.Secrets.xcconfig。在自述文件中,告诉用户 运行 cp Example.Secrets.xcconfig Secrets.xcconfig 然后更新其中的值。现在您可以清楚地看到应用程序正在使用哪些键(在目录中很清楚)。作为奖励,您可以将此文件添加到 Xcode 项目,这样当文件丢失时,它会显示为红色(向用户表明他们确实应该以某种方式获取此文件):

在Info.plist中引用变量:

<dict>
    <key>SECRET_API_KEY</key>
    <string>$(SECRET_API_KEY)</string>
</dict>

在您的代码中,加载存储在 Info.plist 中的变量:

let key = Environment.infoDictionary["SECRET_API_KEY"] as? String

在您的 CI/ Azure 管道中:

运行 echo "SECRET_API_KEY = $SECRET_API_KEY_SAVED_IN_CONTINUOUS_INTEGRATION" >> Secrets.xcconfig

然后你可以只.gitignore文件而不是设置环境变量。当你和其他开发者一起工作时,你只需要给他们这个文件,本地构建不需要做任何其他事情。


所以我不是通过解决您的直接问题来回答您的问题,而是为您提供了一种更常见/规范的方法来解决许多开发人员以前遇到过的这个问题。