CSVファイル読み込み

###1.大まかな処理
####(1)CSVファイルパスを取得(NSBundle)
public func **pathForResource**(name: String?, ofType ext: String?) -> String?

####(2)CSVデータ読み込み(String)
public **init**(contentsOfFile path: String, encoding enc: NSStringEncoding) throws

####(3)CSVデータを1行ずつ読み込む(String)
public func **enumerateLines**(body: (line: String, inout stop: Bool) -> ())

####(4)カンマ区切りで分割(String)
public func **componentsSeparatedByString**(separator: String) -> [String]

*(5)取得したデータを何かに格納する*

###2.コード

```swift:書式
//CSVファイルパスを取得
if let csvFilePath = NSBundle.mainBundle().pathForResource("読み込むファイル名", ofType: "ファイルフォーマット") {
  //CSVデータ読み込み
  do {
    if let csvStringData: String = try String(contentsOfFile: csvFilePath, encoding: NSUTF8StringEncoding) {
      //CSVデータを1行ずつ読み込む
      csvStringData.enumerateLines({ (line, stop) -> () in
        //カンマ区切りで分割
        let wordSourceDataArray = line.componentsSeparatedByString(",")
      })
    }
  } catch let error {
    //ファイル読み込みエラー時
    print(error)
  }
}
```

**作成するもの**
(1)読み込んだCSVファイルのデータを格納するクラス
「WordData」
(2)CSVファイルを読み込むクラス
「WordsDataManager」

```swift:凡例
import Foundation

//==================================================
//1つの単語に関する情報を管理するデータクラス
//==================================================
class WordData {
    
    //単語
    var word: String?
    
    //説明
    var meaning: String?
    
    //単語の番号
    var wordNumber: Int = 0
    
    //クラスが生成された時の処理
    init(wordSourceDataArray: [String]) {
        word = wordSourceDataArray[0]
        meaning = wordSourceDataArray[1]
    }
}

//==================================================
//全ての単語に関する情報を管理するモデルクラス
//==================================================
class WordsDataManager {
    
    //シングルトンオブジェクトを作成
    static let sharedInstance = WordsDataManager()
    
    //単語を格納するための配列
    var wordDataArray = [WordData]()
    
    //現在の単語のインデックス
    var nowWordIndex: Int = 0
    
    //初期化処理
    private init(){
        //シングルトンであることを保証するためにprivateで宣言
    }
    
    //------------------------------
    //単語の読み込み処理
    //------------------------------
    func loadWord() {
        //格納済みの単語があれば一旦削除
        wordDataArray.removeAll()
        //現在の単語のインデックスを初期化
        nowWordIndex = 0
        
        //CSVファイルパスを取得
        if let csvFilePath = NSBundle.mainBundle().pathForResource("words", ofType: "csv") {
            //CSVデータ読み込み
            do {
                if let csvStringData: String = try String(contentsOfFile: csvFilePath, encoding: NSUTF8StringEncoding) {
                    //CSVデータを1行ずつ読み込む
                    csvStringData.enumerateLines({ (line, stop) -> () in
                        //カンマ区切りで分割
                        let wordSourceDataArray = line.componentsSeparatedByString(",")
                        //単語データを格納するオブジェクトを作成
                        let wordData = WordData(wordSourceDataArray: wordSourceDataArray)
                        //単語を追加
                        self.wordDataArray.append(wordData)
                        //単語番号を設定
                        wordData.wordNumber = self.wordDataArray.count
                    })
                }
            } catch let error {
                //ファイル読み込みエラー時
                print(error)
            }
        }
    }
    
    //------------------------------
    //次の単語を取り出す
    //------------------------------
    func nextWord() -> WordData? {
        if nowWordIndex < wordDataArray.count {
            let nextWord = wordDataArray[nowWordIndex]
            nowWordIndex += 1
            return nextWord
        }
        return nil
    }
}
```

###3.詳解

**static let sharedInstance = WordsDataManager()**
・ファイルの読み込みクラスをシングルトンで作成
・「タイププロパティ」=全てのインスタンスが共有する情報用
・「let」=定数で定義
・「sharedInstance」=シングルトンのインスタンス名のベストプラクティス

**private init(){}**
・既定イニシャライザの使用を不可に設定


**NSBundle.mainBundle().pathForResource("words", ofType: "csv")**
・NSBundleはアプリケーションのリソース（クラス、Xib、画像などのファイル）をまとめて管理してくれる仕組みを提供するクラス
・「NSBundle.mainBundle()」=NSBundleを取得する
・「pathForResource」=指定したリソースのパスを取得する

**String(contentsOfFile:ファイルパス文字列, encoding: NSUTF8StringEncoding)**
・func pathForResource(name: String?, ofType ext: String?) -> String?
・エンコードした文字列を作成

**文字列.enumerateLines()**
・public func enumerateLines(body: (line: String, inout stop: Bool) -> ())
・文字列を１行ずつ抜き出す


**文字列.componentsSeparatedByString("文字")**
・引数に指定した文字で文字列を分割する