最近Swiftを触りました。
今回はSwiftで開発するプロジェクトで、.env
ファイルを使って環境変数をビルド時に埋め込む方法を書いていきます。
Swift+Xcode初心者なので間違いなどあれば教えてください。
ビルド時の流れ
やってること自体は単純で、swiftファイルごと作成しています。
- Run Scriptでシェルスクリプトを呼び出す
- スクリプト内で
.env
を読み込み、Environment.swift
を作成する - Environment.swiftを使ってビルド実行
とりあえずやってみる
1. .gitignore
に追記
間違ってcommitしないように、先に追記しておきましょう。
ここで.env
と一緒にEnvironment.swift
も追加しておきます。
#(省略)
.env
Environment.swift
2. .env
を用意する
お馴染みのファイルを用意。場所はプロジェクトのルート直下が良いと思います。
TWITTER_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GYAZO_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
HOGEHOGE=xxxxxxxxxxxxxxxxxxxxxx
3. シェルスクリプトを作成
.env
を読み取って、Environment.swift
を生成するshellscriptです。
引数を2つ取り、1つ目が.envのpath、2つ目が出力先です。
保存先は、こちらもプロジェクトルート直下が良いと思います。
#!/bin/sh
# Copyright (c) 2021 Sho YAMASHITA
code=$(cat <<EOS
import Cocoa
let Env: [String: String] = [
EOS
)
if [ $# -ne 2 ]; then
echo "require 2 arguments." 1>&2
echo "./buildEnv.sh /path/to/.env /output/path" 1>&2
exit 1
fi
if [ -f "$1" ]; then
while IFS='' read -r line || [[ -n "$line" ]]; do
line="${line//[$'\r\n']}"
trimline="${line//[$'\t\r\n ']}"
if [ -n "$trimline" ]; then
KEY="${line%%=*}"
VALUE="${line##*=}"
code=$(cat <<EOS
$code
"$KEY": "$VALUE",
EOS
)
fi
done < "$1"
fi
code=$(cat <<EOS
$code
]
EOS
)
echo "${code}" > "$2/Environment.swift"
exit 0
import Cocoa
部分は必要に応じて変更してください。
4. Run Scriptを追加
XcodeのTARGETS < Build Phases
を開き、左上の+
ボタンからRun Scriptを追加してください。
この時、並び順をCompile Souces
より前に来るように配置してください。
追加したら、以下のようにコマンドを記入します。
"${SRCROOT}/buildEnv.sh" "${SRCROOT}/.env" "${SRCROOT}/${PROJECT}"
ここでまず1回BuildもしくはRunしてみましょう。
上手くいけばプロジェクトディレクトリ配下に、Environment.swift
が生成されているはずです。
5. 環境変数(.env)の値を使用する
生成された Environment.swift
をプロジェクトに追加すれば、あとは変数として使うだけです。
Env["<.envに書いたキー>"]
で呼び出せます。
// ...省略
let twitterToken = Env["TWITTER_TOKEN"]
let clientId = Env["GYAZO_CLIENT_ID"]
生成された環境変数は全てString型になっているので、整数型として使いたい場合などはキャストして下さい。
以上で終わりです。
この方法のメリット
-
.env
を成果物に含める必要がない -
Info.plist
に書く必要がない(成果物の中身見ればデータが見れてしまう) - 管理対象のコードを上書きする事がないので、git管理がしやすい
今回採用しなかった、他の方法
Info.plistに持たせるのが一般的なのでしょうか?
成果物の中身をみられにくい場合(特にiOSアプリなど)や、漏れてもそこまで気にしなくて良い場合は良いのかもしれません。
終わりに
普段Web系の言語に触れていると当たり前のようにある .env
なのですが、これといってベストな解決策が見当たらなかった事に驚きました。
そもそもあまり情報がなかったのは、iOSアプリなどをgit管理してOSSで公開する事が想定されていないからなのか……?
何かご意見等あれば、コメントお待ちしております🙇♂️