SwiftでCSVデータを読み込んでコンソールに出力

Swift 4, iOS 12.1で作りました。

##つくるもの

　準備したCSVデータを読み込んで、コンソールに出力します。


![スクリーンショット 2019-01-11 18.27.59.png](https://qiita-image-store.s3.amazonaws.com/0/93396/ca66788b-e6ee-d16b-a0e1-df8d26d1b9bc.png)

```
【名前】マヌルネコ　【体長】50-65 cm　【体重】2.5-3.5 kg
【名前】ウォンバット　【体長】70-110 cm　【体重】19-33 kg
【名前】イワダヌキ　【体長】50 cm　【体重】4 kg
```

##CSVの準備

　プロジェクトデータを作成したら、CSVファイルを作ります。New FileのOtherの項目からEmptyを選択。
![スクリーンショット 2019-01-11 18.24.05.png](https://qiita-image-store.s3.amazonaws.com/0/93396/1d554159-3895-3940-12a6-ad49734f62a7.png)
　名前を"dataList.csv"にして、プロジェクトフォルダ内に保存します。
![スクリーンショット 2019-01-11 18.24.24.png](https://qiita-image-store.s3.amazonaws.com/0/93396/7138e688-6a12-da94-2a49-c14eec9a537c.png)
　"dataList.csv"には以下のようにデータを入れます。
![スクリーンショット 2019-01-11 18.27.59.png](https://qiita-image-store.s3.amazonaws.com/0/93396/ca66788b-e6ee-d16b-a0e1-df8d26d1b9bc.png)
　動物ごとの名前、体長、体重を分けて書いています。

##ViewController

###CSVファイルのパスを取得

　ViewControllerのvieDidLoad()内にコードを入れていきます。

```swift:ViewController.swift
class ViewController: UIViewController {
    var csvLines = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        guard let path = Bundle.main.path(forResource:"dataList", ofType:"csv") else {
            print("csvファイルがないよ")
            return
        }   
    }
```

　csvLinesは文字列の配列を宣言しています。

 Bundle.mainでアプリケーション内にバンドルされたファイルを、.pathでパスを参照します。forResourceはファイル名、ofTypeは拡張子です。

　頭にguardをつけたメソッドでエラーがあった場合、エラーメッセージが出力されます。


###CSVファイルのデータを取得

　先ほど記述したコード(guard else{return})の下に以下のコードを記述します。

```swift:ViewController.swift
        let csvString = String(contentsOfFile: path, encoding: String.Encoding.utf8)
        csvLines = csvString.components(separatedBy: .newlines)
```
　＊この時点ではエラーが出ますが無視してください。

　csvStringではCSVのデータを文字列に変換しています。String()で文字列に変換しており、contentsOfFileがファイルのパスで先ほど取得したもの、encoding:は文字コードの指定です。一般的なUTF8にしています。

 csvStringには以下の文字列が入りました：

```swift:csvString
マヌルネコ,50-65,2.5-3.5
ウォンバット,70-110,19-33
イワダヌキ,50,4
```

　csvLinesでは、この文字列を改行ごとに分けて配列データにします。.componentsは文字列を分割するメソッドです、separatedBy:で分割の条件を指定し、.newlinesは改行を指しています。

　csvLinesは配列となりこのようになりました：

```swift:csvLines
["マヌルネコ,50-65,2.5-3.5", "ウォンバット,70-110,19-33", "イワダヌキ,50,4", ""]
```

###エラー処理

　このままでは、CSVにデータが入っていなかった時にクラッシュするのでエラー処理を追記します。

```swift:ViewController.swift
        do {
            let csvString = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
            csvLines = csvString.components(separatedBy: .newlines)       
        } catch let error as NSError {
            print("エラー: \(error)")
            return
        }
```

　do-catchで囲み、エラーが起きた場合は実行を中断しエラーを出力するようにしています。

###データの詳細を取得

　上記コードに続いて以下のコードを記述します。

```swift:ViewController.swift
        for animalData in csvLines {
            let animalDetail = animalData.components(separatedBy: ",")
            print("【名前】\(animalDetail[0])　【体長】\(animalDetail[1]) cm　【体重】\(animalDetail[2]) kg")
        }
```

　配列の各データを取り出し、コンマ(,)で分割して、さらに配列に分けて、コンソールに出力します。

　.componentsでは今度はseparatedBy: ","にしており、コンマで分割しました。これにより、animalDataには以下のような配列が入ります。

```swift:animalData
["マヌルネコ","50-65","2.5-3.5"]
```

　これを実行するとコンソールには以下のように出力されます：

```
【名前】マヌルネコ　【体長】50-65 cm　【体重】2.5-3.5 kg
【名前】ウォンバット　【体長】70-110 cm　【体重】19-33 kg
【名前】イワダヌキ　【体長】50 cm　【体重】4 kg
(lldb)
```

　そしてエラーが出たと思います。

　これは最後に改行が入っているので、printが成功しなかったからです。Xcode内で作成したCSVは最後に改行が入るため、これを削除するコードを追記します。

###最後の行を削除する

　＊これは一時しのぎの方法ですので、他の方法で作成したCSVでは必要なデータが削除される恐れがあります。

　CSVデータを改行ごとに分けて配列データにしたあと、.removeLast()を使って、配列の最後のデータを削除します。

```swift:ViewController.swift
        do {
            let csvString = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
            csvLines = csvString.components(separatedBy: .newlines)
            csvLines.removeLast()         //これを追加
        } catch let error as NSError {
            print("エラー: \(error)")
            return
        }
```

　これでエラー無く出力されました。

```
【名前】マヌルネコ　【体長】50-65 cm　【体重】2.5-3.5 kg
【名前】ウォンバット　【体長】70-110 cm　【体重】19-33 kg
【名前】イワダヌキ　【体長】50 cm　【体重】4 kg
```

##すべてのコード

　完成したコードがこちらになります。

```swift:ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        var csvLines = [String]()
        
        guard let path = Bundle.main.path(forResource:"dataList", ofType:"csv") else {
            print("csvファイルがないよ")
            return
        }
        
        do {
            let csvString = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
            csvLines = csvString.components(separatedBy: .newlines)
            csvLines.removeLast()
        } catch let error as NSError {
            print("エラー: \(error)")
            return
        }
        
        for animalData in csvLines {
            let animalDetail = animalData.components(separatedBy: ",")
            print("【名前】\(animalDetail[0])　【体長】\(animalDetail[1]) cm　【体重】\(animalDetail[2]) kg")
        }
        
    }
    
}
```