はじめに
GitHubにPublicなリポジトリでAPIキーとかを隠蔽したまま公開したい!っていうことありませんか。
.env ファイルとか作ってそれぞれの環境に合わせてビルドできるようになりたいーっていうやつ
ついでに Info.plist にAPIキー書くやつたまにあるけどそれもやりたいっていう
環境
- Xcode9.1(8.3.3でも確認済み)
- macOS 10.12.6
- swift 4.0.2
ソースコード編
手順
- Xcodeプロジェクトの作成(省略)
-
.envおよび.env.sampleの作成
TWITTER_CONSUMER_KEY=''
TWITTER_CONSUMER_SECRET=''
こんな感じに作って、どちらとも <PROJECT_NAME>.projectpbxproj が読める状態にする。
3. .gitignore 設定
$ echo "/path/to/.env" >> /path/to/.gitignore
この時点で git add .env などしてなかったらGit管理下になっていないのでいいかと思いますが、Git管理下になっていた場合、以下
$ git rm --cached /path/to/.env
git clone とかした時点で上の画像みたいに File NotFound 状態になったらOK
4. 環境変数読み込み
今回は swift4.0.2 で確認してるのでそれぞれの環境に合わせて実装等お願いします。
AppDelegate.swift の func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { } に
・・・
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
guard let path = Bundle.main.path(forResource: ".env", ofType: nil) else {
fatalError("Not found: '/path/to/.env'.\nPlease create .env file reference from .env.sample")
}
let url = URL(fileURLWithPath: path)
do {
let data = try Data(contentsOf: url)
let str = String(data: data, encoding: .utf8) ?? "Empty File"
let clean = str.replacingOccurrences(of: "\"", with: "").replacingOccurrences(of: "'", with: "")
let envVars = clean.components(separatedBy:"\n")
for envVar in envVars {
let keyVal = envVar.components(separatedBy:"=")
if keyVal.count == 2 {
setenv(keyVal[0], keyVal[1], 1)
}
}
} catch {
fatalError(error.localizedDescription)
}
・・・
}
・・・
な感じに書く。 .env がなかったら fatalError が発生する。
メソッドぐちゃぐちゃになるので自分は別のメソッド作りました。
さっきの続きに。
今回は TwitterKit のAPIキーをサンプルに
・・・
let env = ProcessInfo.processInfo.environment
Twitter.sharedInstance().start(withConsumerKey: env["TWITTER_CONSUMER_KEY"]!, consumerSecret: env["TWITTER_CONSUMER_SECRET"]!)
.env の左辺をキーとして取得できるようになってたら完了!
Info.plist 編
手順
ソースコード編 の 4 の手順までは同じ
-
Run Scriptを作成。
みなさんに説明するまでもなく...
この Run Script は Copy Bundle Resources (○ items) よりも上に配置するようにしないと上手く動かないです
2. PlistBuddy を使うスクリプトの記述
PlistBuddy の説明はパスで、調べれば Build Number をなんとかーっていうのがたくさん出てくると思います!
また、 TwitterKit の例ですが、URLSchemeを事前に用意しておいてそこを twitterkit-<API_KEY> に置き換えるといったような処理
plistBuddy="/usr/libexec/PlistBuddy"
infoPlistFileSource="${SRCROOT}/${INFOPLIST_FILE}"
infoPlistFileDestination="${TEMP_DIR}/Preprocessed-Info.plist"
. /path/to/.env
$plistBuddy -c "Set :CFBundleURLTypes:0:CFBundleURLSchemes:0 twitterkit-${TWITTER_CONSUMER_KEY}" "${infoPlistFileDestination}"
Info.plist の特定のキーへのPATHは普通に辞書と配列でアクセスできるので説明はなしで
試しにビルドして、 twitterkit-<API_KEY>:// のURLSchemeをSafari等でも UIApplication.shared.canOpenURL(URL) で行ければできてると思います。
最後に
ArchiveしてExportした .ipa ファイルを unzip したら Info.plist とかは見られるのであくまでも外部リモートに公開してるときだけ隠蔽できるという感じでした。
今回は .env ファイル内の値を環境変数として読み込むだけでしたが、普通に母艦の環境変数も使えると思うので参考になればと思います。




