iOS
Swift
swift4

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

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

つくるもの

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

スクリーンショット 2019-01-11 18.27.59.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
 名前を"dataList.csv"にして、プロジェクトフォルダ内に保存します。
スクリーンショット 2019-01-11 18.24.24.png
 "dataList.csv"には以下のようにデータを入れます。
スクリーンショット 2019-01-11 18.27.59.png
 動物ごとの名前、体長、体重を分けて書いています。

ViewController

CSVファイルのパスを取得

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

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})の下に以下のコードを記述します。

ViewController.swift
        let csvString = String(contentsOfFile: path, encoding: String.Encoding.utf8)
        csvLines = csvString.components(separatedBy: .newlines)

 *この時点ではエラーが出ますが無視してください。

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

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

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

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

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

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

エラー処理

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

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で囲み、エラーが起きた場合は実行を中断しエラーを出力するようにしています。

データの詳細を取得

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

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

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

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

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()を使って、配列の最後のデータを削除します。

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

すべてのコード

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

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")
        }

    }

}