Help us understand the problem. What is going on with this article?

CSVファイル読み込み

More than 3 years have passed since last update.

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.コード

書式
//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」

凡例
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) -> ())
・文字列を1行ずつ抜き出す

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away