4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Swift】FireStore × TableViewの実装(データの取得から反映までの格闘)

Posted at

はじめに

TableViewとFireStoreを掛け合わせた実装の際、データ取得から反映(特に反映)で詰まっていたので、次回実装時にスムーズに実装できるようにメモに残したい。

TL;DL

実装の際のポイント
// tableView.reloadData()の実装のタイミングを間違うと表示されない
tableView.reloadData()  // こいつ!!!

実装例

① 取得するデータを格納する配列を用意

ViewController.swift
var memoDataArray: [MemoDataStore] = []
// ついでにFirestoreの下準備も
let currentUser = Auth.auth().currentUser
let db = Firestore.firestore()

② TableViewのデータの取得と更新

今回ここが抜けていたのが原因で表示されませんでした。

ViewController.swift
override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 毎回データ更新してくれるように、viewWillAppearの中に記述する
        memoDataArray = getData()
}

func getData() -> [MemoDataStore] {
    let ref = db.collection("todos")
    ref.getDocuments { (snaps, err) in
        if let err = err {
            print("Error getting documents: \(err)")
            return
        }
        self.memoDataArray = snaps!.documents.map { document -> MemoDataStore in
            let data = MemoDataStore(document: document)
            return data
        }
        
     // こいつ!!!!
        // データ取得が終わったタイミングでtableViewをリロードデータ
        self.tableView.reloadData()
    }
    return memoDataArray
}

class MemoDataStore: NSObject{
    var todoText: String?
    var detailText: String?
    var dateText: String?
    init(document: QueryDocumentSnapshot) {
        let dic = document.data()
        self.todoText = dic["todo"] as? String
        self.detailText = dic["detail"] as? String
        self.dateText = dic["date"] as? String
    }

}

配列に格納されたデータをTableViewに適応

ViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // カスタムセル使用しているが、今回は記載を省略
    let cell = tableView.dequeueReusableCell(withIdentifier: "MemoCell") as! FirstViewTableViewCell
    cell.setCell(memo: memoDataArray[indexPath.row].todoText!, date: 
    memoDataArray[indexPath.row].dateText!)
    return cell
}

これでFireStoreからデータを取得して、TableViewに表示するまでの実装できました。

まとめ

  1. tableView.reloadData()は、tableViewのデータを更新ためのメソッドであり、TableView上のデータにコード上で変更を加えた際は、変更が完了したタイミングで、reloadData()を忘れないこと

  2. 今回で言うと、FireStoreからデータが取得される前に、tableViewの表示が実装されて、データが配列に格納されていない状態を参照していたので、何も表示されなかった。

  3. つまり、TableViewの表示のコードが読み込まれてから、用意した配列にデータが入っているため、何も表示されていないイメージ。

  4. 特に外部APIを叩いた際は、取得までに時間がかかり、非同期的にデータが取得されるため、iOSのライフサイクルに準拠して、実装することが大切

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?