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

## 1. Custom Configurationを追加する  
#### step1. PROJECT -> info -> Configurationsから追加
「+」->「Duplicate "Debug" Configuration」  
追加前
![step1-1.png](https://qiita-image-store.s3.amazonaws.com/0/37319/cc2b6c9a-979a-3376-f656-3670fbd58942.png)

追加後
![step1-2.png](https://qiita-image-store.s3.amazonaws.com/0/37319/9743c637-5946-9a62-befb-a95cff8ac192.png)

## 2. Info.plistを編集する  
#### step1. Configurationを追加する  
Key: Configuration, Value: ${CONFIGURATION} を追加  
![step2-1.png](https://qiita-image-store.s3.amazonaws.com/0/37319/fa5c45ca-359d-9869-8803-c189c4720ee6.png)

#### step2. 出力を確認  

```Swift: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を変更する  
![step3-1.png](https://qiita-image-store.s3.amazonaws.com/0/37319/4560745f-fd56-f0ff-e80e-1741f7835287.png)

#### step2. CocoaPodsを更新する（CocoaPods未使用の場合は不要）
追加したConfiguration（ここではDevelopment）のxcconfigが無いとエラーになるので更新する

```
$ pod update
```

## 4. Configuration.plistを追加する  
#### step1. plistを新規作成  
![step4-1.png](https://qiita-image-store.s3.amazonaws.com/0/37319/0094d00f-76bd-6a92-2e10-dfd8038f83c2.png)

#### step2. 項目を追加  
![step4-2.png](https://qiita-image-store.s3.amazonaws.com/0/37319/a297affa-de08-4e94-daba-0dc9b2456e9f.png)

#### step3. 出力を確認  

```Swift: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クラスを編集  

```Swift: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. 動作確認

```Swift: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](http://code.tutsplus.com/tutorials/ios-quick-tip-managing-configurations-with-ease--mobile-18324)
[THE RIGHT WAY TO WRITE A SINGLETON](http://krakendev.io/blog/the-right-way-to-write-a-singleton)