環境
言語:Swift 5.4
開発環境;xcode 12.5
クラウドデータベース:Cloud Firestore
やりたいこと
Swift×FirestoreでToDoリストアプリを作っています。
最終的には、マルチデバイスでどのデバイスとも同期できるようにしたいと思い、
下記のページを参考にFirestoreと連携するTableViewのアプリを作成しています。
【Firebase×Swift】データ取得とTableView表示(後編)〜取得データの変換とセル表示〜
ToDoのクラスとしてMyTodoクラスを作り、MyTodoクラスからインスタンス(myTodo)を作り、インスタンスの配列を処理することでToDoの追加・削除等の機能を作っていきたいと考えています。
困っていること
MyTodoクラスを元に、タスクを追加するためのインスタンスmyTodoを作成しようとすると、xcodeで
let myTodo = MyTodo()
の箇所で下記のエラーが出てビルドできないです。
Missing argument for parameter 'document' in call
MyTodo() をMyTodo(document: QueryDocumentSnapshot)としたりしましたがエラーは消えず、ハマってしまいこれ以上進めない状況です。対処法等、分かりましたら教えていただけると助かります。
なお、CloudFirestoreとクライアントでデータの送受信ができるところまでは確認できています。
MyTodoクラスの初期化(init)のところがいけないのでしょうか。
コード
swift
1import UIKit 2import Firebase 3import FirebaseFirestoreSwift 4 5 6class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 7 8 //************************************************* 9 //ToDoのテキストを格納する配列の定義 10 //************************************************* 11 var todoList = [MyTodo]() 12 let db = Firestore.firestore() 13 14 //************************************************* 15 //UITableViewのoutlet定義 16 //************************************************* 17 @IBOutlet weak var tableView: UITableView! 18 19 //************************************************* 20 //画面の初回ロード時の処理 21 //************************************************* 22 override func viewDidLoad() { 23 super.viewDidLoad() 24 print("ログ_viewdidload:start") 25 26 27 //++++++++++++++++++++++++++++++++++++++++++++ 28 //Firestoreからドキュメントのデータを取得して、todoListのデータ型に変換し配列の各要素に入れる 29 //++++++++++++++++++++++++++++++++++++++++++++ 30 //Firestoreからドキュメントのデータ取得。 31 print("ログ_viewdidload:Getting documents is start") 32 db.collection("todo").getDocuments() { (querySnapshot, err) in 33 if let err = err { 34 print("ログ_viewdidload:Error getting documents(err)") 35 } else { 36 print("ログ_viewdidload:Getting documents is success!") 37 for document in querySnapshot!.documents{ 38 print("ログ_viewdidload:documentの中身を確認(document.data())") 39 } 40 } 41 42 self.todoList = querySnapshot!.documents.map { 43 document in let data = MyTodo(document: document) 44 return data 45 } 46 } 47 } 48 49 //************************************************* 50 // +ボタンをタップした時の処理(タスク入力オブジェクトの作成・処理) 51 //************************************************* 52 53 @IBAction func tapAddButton(_ sender: Any) { 54 55 // タスク入力オブジェクトとなるアラートダイアログを生成 56 let alertController = UIAlertController( 57 title: "ToDo追加", 58 message: "ToDoを入力してください", 59 preferredStyle: UIAlertController.Style.alert 60 ) 61 62 // テキストエリアを追加 63 alertController.addTextField(configurationHandler: nil) 64 65 //************************************************* 66 //OKボタンの配置、ボタン押下時の処理 67 //************************************************* 68 // OKボタンを追加 69 let okAction = UIAlertAction( 70 title: "OK", 71 style: UIAlertAction.Style.default 72 ){ 73 (action: UIAlertAction) in 74 // OKボタンがタップされたときの処理(ToDoの配列に入力値を挿入。テーブルの先頭行に挿入する) 75 if let textField = alertController.textFields?.first { 76 77 let myTodo = MyTodo() //<--ココ! MyTodoクラスをインスタンス化してmyTodo定数を生成したい 78 myTodo.todoTitle = textField.text! 79 self.todoList.insert(myTodo, at: 0) 80 81 // テーブルに行を追加 82 self.tableView.insertRows( 83 at: [IndexPath(row: 0, section: 0)], 84 with: UITableView.RowAnimation.right 85 ) 86 87 //追加したToDoについて、Firestoreのtodoコレクションに新規のtodoドキュメントを追加 88 let ref: DocumentReference? = nil 89 self.db.collection("todo").addDocument(data: [ 90 "todoTitle": myTodo.todoTitle!, 91 "todoDone": false 92 ]) { err in 93 if let err = err { 94 print("Error adding document: (err)") 95 } else { 96 print("Document added with ID: (ref!.documentID)") 97 } 98 } 99 } 100 } 101 102 // OKボタンがタップされたときの処理 103 alertController.addAction(okAction) 104 105 //************************************************* 106 //キャンセルボタンの配置、ボタン押下時の処理 107 //************************************************* 108 // CANCELボタンがタップされたときの処理 109 let cancelButton = UIAlertAction( 110 title: "CANCEL", 111 style: UIAlertAction.Style.cancel, 112 handler: nil 113 ) 114 115 // CANCELボタンを追加 116 alertController.addAction(cancelButton) 117 // アラートダイアログを表示 118 present(alertController, animated: true, completion: nil) 119 } 120 121 122 //************************************************* 123 // テーブルの行数返却 124 //************************************************* 125 // テーブルの行数を返却する 126 127 128 func tableView( 129 _ tableView: UITableView, 130 numberOfRowsInSection section: Int 131 ) -> Int { 132 // Todoの配列の長さを返却する 133 print("ログ_tableView_numberOfRowsInSection:配列の長さは(todoList.count)") 134 135 return todoList.count 136 } 137 138 //************************************************* 139 // テーブルのセルの表示(テーブルの行ごとにセルを返却) 140 //************************************************* 141 // テーブルの行ごとのセルを返却する 142 func tableView( 143 _ tableView: UITableView, 144 cellForRowAt indexPath: IndexPath 145 ) -> UITableViewCell { 146 // Storyboardで指定したtodoCell識別子を利用して再利用可能なセルを取得する 147 let cell = tableView.dequeueReusableCell( 148 withIdentifier: "todoCell", 149 for: indexPath 150 ) 151 // 行番号に合ったToDoの情報を取得 152 let myTodo = todoList[indexPath.row] 153 print("ログ_tableView_cellForRowAt:myTodoの中身は(todoList[indexPath.row])") 154 print("ログ_tableView_cellForRowAt:行番号に合ったToDoは(String(describing: myTodo.todoTitle))") 155 156 // セルのラベルにToDoのタイトルをセット 157 cell.textLabel?.text = myTodo.todoTitle 158 159 160 // セルのチェックマーク状態をセット 161 if myTodo.todoDone { 162 // チェックあり 163 cell.accessoryType = UITableViewCell.AccessoryType.checkmark 164 } else { 165 // チェックなし 166 cell.accessoryType = UITableViewCell.AccessoryType.none 167 } 168 169 return cell 170 } 171 172 173 174 //************************************************* 175 // セルをタップした時の処理(チェックを入れたり外したり) 176 //************************************************* 177 // セルをタップしたときの処理 178 func tableView( 179 _ tableView: UITableView, 180 didSelectRowAt indexPath: IndexPath 181 ) { 182 let myTodo = todoList[indexPath.row] 183 184 if myTodo.todoDone { 185 // 完了済みの場合は未完了に変更 186 myTodo.todoDone = false 187 } else { 188 // 未完の場合は完了済みに変更 189 myTodo.todoDone = true 190 } 191 192 // セルの状態を変更(特定の行だけリロードする) 193 tableView.reloadRows( 194 at: [indexPath], 195 with: UITableView.RowAnimation.none 196 ) 197 198 let ref: DocumentReference? = nil //Firestoreでドキュメントを指定するため、タップしたドキュメントIDを取得 199 myTodo.todoId = ref!.documentID 200 201 //フラグを変更したToDoについて、Firestoreのtodoコレクションの該当するtodoドキュメントのフラグを変更 202 db.collection("todo").document(myTodo.todoId!).updateData([ 203 "todoDone": myTodo.todoDone, 204 ]) { err in 205 if let err = err { 206 print("Error updating document: (err)") 207 } else { 208 print("Document successfully updated") 209 } 210 } 211 212 } 213} 214//************************************************* 215// MyTodoクラスを作成 216//************************************************* 217 218class MyTodo: NSObject{ 219 var todoId: String? 220 var todoTitle: String? 221 var todoDone: Bool = false 222 223 //取得したデータをFirestoreのデータ型に当てはめていくための型(MyTodoのデータ型) 224 init(document: QueryDocumentSnapshot) { 225 self.todoId = document.documentID 226 self.todoTitle = document.data()["todoTitle"] as? String 227 self.todoDone = document.data()["todoDone"] as! Bool 228 } 229}
回答1件
あなたの回答
tips
プレビュー