🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

1969閲覧

【SwiftUI】関数が値を返すのを待ちたい

A.ESK

総合スコア1

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/12/19 07:56

こんにちは。
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}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

body の先頭で getData を呼ぶとデータを取得して表示を更新しようとするたびに再読み込みしてしまって無限ループになるので、onAppear で処理すると良いでしょう。

diff

1 struct 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+ .onAppear { 19+ getter.getData { (retrievedList) in 20+ self.postList = retrievedList! 21+ } 22+ } 23 } 24 }

投稿2020/12/25 06:32

hoshi-takanori

総合スコア7899

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問