Firestoreから取得したデータを画面にカテゴリーごとに表示したいです。
カテゴリーごとに並び替えを実行するまでにFirestoreが読み込みを完了していたい為、
DispatchSemaphoreを入れ処理を実行しましたが、以下エラーが発生し解決策がわかりません。
「Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.」
問題点、解決先のご教示願います。
func load() -> [itemData] { var datas: [itemData] = [] var semaphore : DispatchSemaphore! let db = Firestore.firestore() semaphore = DispatchSemaphore(value: 0) db.collection("paper").getDocuments() { (snaps, error) in if let error = error { fatalError("(error)") } guard let snapshot = snaps else { return } for document in snapshot.documents { let item = document.data() datas += [itemData( id:item["id"] as! Int, name: item["name"] as! String, photo: item["photo"] as! String, kind: item["kind"] as! Int, category: item["category"] as! String] } semaphore.signal() //print(datas) } print("semaphore wait...") semaphore.wait() print("complete!") return datas }
DispatchSemaphore なんか使わずに非同期処理しましょう。
ありがとう御座います。
同期を取ろうとした理由が、表示する際に
@EnvironmentObjectで定義し、以下処理でエラーになります。
var categories: [String: [ItemData]] {
Dictionary(
grouping: Datas, by: { $0.category }
)
}
Categoryでグルーピングしたいので、同期とる以外によい方法はありますでしょうか
その categories が ObservableObject のサブクラスの @Published var ってことなら、初期値を空または nil にしておいて、非同期の結果が返ってきたら更新すれば良いかと。
ありがとう御座います。
エラーがなくなりました。ただデータが表示できません。
どうも、上記記載のソースコード
db.collection("paper").getDocuments() { (snaps, error) in
内ではprint(datas)でデータは入りますが、returnを通らずに元々の参照側
@Published var itemList: [itemData] = load()
ItemListは空データのままになっています。
ご教示願います。
load メソッドというか、その中で呼んでる getDocuments は、Firestore にリクエストを投げるだけで、結果を待たずに return するため、load メソッド自体も空データのまま return します。
その後、Firestore から結果が帰ってきたら getDocuments() の後ろのクロージャ { (snaps, error) in 〜 } が実行されますので、この中で改めて itemList の値を更新すると良いでしょう。
解決いたしました、ありがとう御座いました。
あなたの回答
tips
プレビュー