こんにちは。
SwiftUIとFirebaseを用いてアプリを作成しています。
問題
FirebaseのCloud Firestoreに格納されているデータを、変数に代入した後にその変数を使いたいのですが、
値が代入される前に次のコードが実行されてしまうため困っています。
解決策をご存知の方がいらっしゃいましたら、ご教示ください。
現状
このGetData() 関数内で配列を作成し、その配列を返しています。
Swift
1 func getData() -> [Post]{ 2 3 var postList : [Post] = [] 4 5 db.collection("Item").getDocuments() { (querySnapshot, err) in 6 if let err = err { 7 print("Error getting documents: (err)") 8 //completion(nil) 9 } else { 10 for document in querySnapshot!.documents { 11 12 // Set values of post 13 self.post.postId = document.documentID 14 self.post.itemName = document.get("itemName") as! String;() 15 self.post.shopName = document.get("shopName") as! String;() 16 self.post.itemImageUrl = document.get("itemImageUrl") as! String;() 17 self.post.ratings = document.get("ratings") as! Double;() 18 self.post.caption = document.get("caption") as! String;() 19 20 postList.append(self.post) 21 } 22 } 23 } 24 return postList 25 }
そして、その配列をこのTimeLineViewで使いたいです。
Swift
1struct TimeLineView: View { 2 3 let getter = GetCloudStoreDataController() 4 let user = User(name: "egawa", icon: UIImage(named: "PosterSample")) 5 @State var postList:[Post] = [] 6 7 var body: some View { 8 9 // ここでListが代入される前に次に進んでしまう。 10 let postList = getter.getData() 11 12 List { 13 ForEach(postList){ post in 14 SinglePostView(user: user, post: post) 15 } 16 } 17 } 18}
試したこと
@escapingを使用して、関数が値が返すのを待ってから、代入しようと思い、上記のコードをこのように書き換えました。
しかし、
Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols
と、エラーが出て来て、どのように対処すれば良いかわからなくなっています。
Swift
1 func getData(completion: @escaping ([Post]?) -> Void){ 2 3 var postList : [Post] = [] 4 5 db.collection("Item").getDocuments() { (querySnapshot, err) in 6 if let err = err { 7 print("Error getting documents: (err)") 8 completion(nil) 9 } else { 10 for document in querySnapshot!.documents { 11 12 // Set values of post 13 self.post.postId = document.documentID 14 self.post.itemName = document.get("itemName") as! String;() 15 self.post.shopName = document.get("shopName") as! String;() 16 self.post.itemImageUrl = document.get("itemImageUrl") as! String;() 17 self.post.ratings = document.get("ratings") as! Double;() 18 self.post.caption = document.get("caption") as! String;() 19 20 // Append values of posts to the array 21 postList.append(self.post) 22 } 23 completion(postList) 24 } 25 } 26 } 27
swift
1struct TimeLineView: View { 2 3 let getter = GetCloudStoreDataController() 4 let user = User(name: "egawa", icon: UIImage(named: "PosterSample")) 5 @State var postList:[Post] = [] 6 7 var body: some View { 8 9 getter.getData { (retrievedList) in 10 self.postList = retrievedList! 11 } 12 13 List { 14 ForEach(postList){ post in 15 SinglePostView(user: user, post: post) 16 } 17 } 18 } 19}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。