前提・実現したいこと
環境はXcode10.0.0 Swift4.0です。
Todoアプリを作っています。データベースとしてはFirestoreを用いております。
削除、修正が正しく作動しないので、どこが間違っているかをお教えいただきたいです。
発生している問題・エラーメッセージ
UserDefaultで保存していた時は、配列内のタスクを全部まとめて上書きしておりました。
イメージ的には、タスクが全部書かれたファイルを上書き保存する感じです。
Firestoreで取り組んでいる今回は配列に入ったタスクを1件ずつFirestoreに保存しています。
上書き時はIDを使って上書きしていますが、コードをよく読むと読み出しているときにIDをタスクに保持するようになっていません。この解消方法をご教授いただきたいです。
該当のソースコード
FirestoreTaskRepository.swift
Swift4.0
1import Foundation 2import FirebaseFirestore 3 4class FirestoreTaskRepository: TaskRepositoryProtocol { 5 6 let db = Firestore.firestore() 7 8 init(){ 9 let settings = db.settings 10 settings.areTimestampsInSnapshotsEnabled = true 11 db.settings = settings 12 } 13 14 // ユーザー毎のデータベースへの参照を取得する 15 private func getCollectionRef () -> CollectionReference { 16 guard let uid = User.shared.getUid() else { 17 fatalError ("Uidを取得出来ませんでした。") 18 } 19 return db.collection("users").document(uid).collection("tasks") 20 } 21 22 func save(_ tasks: [Task], completion: (() -> Void)) { 23 // TODO トランザクション 24 let collectionRef = getCollectionRef() 25 tasks.forEach { (task) in 26 if let id = task.id { 27 let documentRef = collectionRef.document(id) 28 documentRef.setData(task.toData()) 29 } else { 30 31 let documentRef = collectionRef.addDocument(data: task.toData()) 32 task.id = documentRef.documentID 33 } 34 } 35 36 // firestoreへの保存は非同期ではない(後でバックグラウンドで同期をしている?) 37 completion() 38 } 39 40 func load(completion: @escaping (([Task]) -> Void)) { 41 print ("データロード") 42 var tasks: [Task] = []; 43 let collectionRef = getCollectionRef() 44 collectionRef.getDocuments { (querySnapshot, error) in 45 if let error = error { 46 print (error.localizedDescription) 47 }else if let documents = querySnapshot?.documents { 48 documents.forEach({ (document) in 49 if document.exists { 50 let data = document.data() 51 let task = Task(data: data) 52 tasks.append(task) 53 } 54 }) 55 } 56 completion(tasks) 57 } 58 59 } 60} 61 62
Task.swift
Swift4.0
1 2import UIKit 3 4class Task: Codable { 5 var id: String? 6 var title: String? 7 var note: String? 8 var latitude: Double? 9 var longitude: Double? 10 11 enum CodingKeys: String, CodingKey { 12 case title 13 case note 14 case latitude 15 case longitude 16 } 17 18 init(title _title: String) { 19 self.title = _title 20 } 21 22 init(data: [String: Any]) { 23 if let title = data["title"] as? String { 24 self.title = title 25 } 26 if let note = data["note"] as? String { 27 self.note = note 28 } 29 if let latitude = data["latitude"] as? Double { 30 self.latitude = latitude 31 } 32 if let longitude = data["longitude"] as? Double { 33 self.longitude = longitude 34 } 35 } 36 37 required init(from decoder: Decoder) throws { 38 let container = try decoder.container(keyedBy: CodingKeys.self) 39 self.title = try container.decode(String.self, forKey: .title) 40 self.note = try container.decode(String.self, forKey: .note) 41 self.latitude = try container.decode(Double.self, forKey: .latitude) 42 self.longitude = try container.decode(Double.self, forKey: .longitude) 43 } 44 func encode(to encoder: Encoder) throws { 45 var container = encoder.container(keyedBy: CodingKeys.self) 46 try container.encode(title, forKey: .title) 47 try container.encode(note, forKey: .note) 48 try container.encode(latitude, forKey: .latitude) 49 try container.encode(longitude, forKey: .longitude) 50 } 51 52 func toData() -> [String: Any] { 53 return [ 54 "title": self.title!, 55 "note": self.note!, 56 "latitude": self.latitude!, 57 "longitude": self.longitude! 58 ] 59 } 60 61} 62 63
試したこと
他のファイル情報が必要でしたらお教えいただけると幸いです。
”Firestoreで取り組んでいる今回は配列に入ったタスクを1件ずつFirestoreに保存しています。
上書き時はIDを使って上書きしていますが、コードをよく読むと読み出しているときにIDをタスクに保持するようになっていません。”
というのは頂いたヒントなのですが、どのように修正したら良いかが分かっておりません…。ロード部分に問題があるのかと思うのですが…。
回答1件
あなたの回答
tips
プレビュー