はじめに
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
ファイル内の値を環境変数として読み込むだけでしたが、普通に母艦の環境変数も使えると思うので参考になればと思います。