Edited at

Swiftでplistを利用して環境(開発、本番等)ごとに設定値を変える

More than 1 year has passed since last update.


1. Custom Configurationを追加する


step1. PROJECT -> info -> Configurationsから追加

「+」->「Duplicate "Debug" Configuration」


追加前

追加後


2. Info.plistを編集する


step1. Configurationを追加する

Key: Configuration, Value: ${CONFIGURATION} を追加



step2. 出力を確認


AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

// Configuration取得
let configuration = NSBundle.mainBundle().infoDictionary!["Configuration"]
print("Current Configuration > \(configuration)")

return true
}


こんな感じに出力されればOK

Current Configuration > Optional(Debug)


3. Schemesを変更する


step1. Edit SchemesからBuild Configurationを変更する


step2. CocoaPodsを更新する(CocoaPods未使用の場合は不要)

追加したConfiguration(ここではDevelopment)のxcconfigが無いとエラーになるので更新する

$ pod update


4. Configuration.plistを追加する


step1. plistを新規作成


step2. 項目を追加


step3. 出力を確認


AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

let mainBundle = NSBundle.mainBundle()
// Configuration取得
let configuration = mainBundle.infoDictionary!["Configuration"]

// Configurations.plist読み込み
let path = mainBundle.pathForResource("Configurations", ofType: "plist")
let configurations = NSDictionary(contentsOfFile: path!)

// Load Variables for Current Configuration
let variables = configurations?.objectForKey(configuration!) as! [String : AnyObject]

print(variables["APIEndpoint"])

return true
}


こんな感じに出力されればOK

Optional(http://development.example.com)


5. 使いやすくする


step1. AppConfクラスを新規作成

(省略)


step2. AppConfクラスを編集


AppConf.swift

import Foundation

final class AppConf {

private static let sharedInstance = AppConf()
private var configuration: String
private var variables: [String: AnyObject]

private init() {

// Singletonの確認用
print("Configuration initialization")

let mainBundle = NSBundle.mainBundle()
// Fetch Current Configuration
self.configuration = (mainBundle.infoDictionary?["Configuration"]) as! String

// Load Configurations
guard let path = mainBundle.pathForResource("Configurations", ofType: "plist") else {
self.variables = [:]
return
}
let configurations = NSDictionary(contentsOfFile: path)
// Load Variables for Current Configuration
self.variables = configurations?.objectForKey(self.configuration) as! [String : AnyObject]
}

class func Configuration() -> String {
return sharedInstance.configuration
}

class func APIEndpoint() -> String {
guard let endpoint = sharedInstance.variables["APIEndpoint"] else {
return ""
}
return endpoint as! String
}

class func isLoggingEnabled() -> Bool {
guard let enabled = sharedInstance.variables["LoggingEnabled"] else {
return false
}
return enabled as! Bool
}
}



step3. 動作確認


AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

for i in 1...5 {
print("\(i)回目: \(AppConf.APIEndpoint())")
}

return true
}


こんな感じに出力されればOK

Configuration initialization

1回目: http://development.example.com
2回目: http://development.example.com
3回目: http://development.example.com
4回目: http://development.example.com
5回目: http://development.example.com


6. 参考にしたサイト

iOS Quick Tip: Managing Configurations With Ease

THE RIGHT WAY TO WRITE A SINGLETON