Cloud Firestore はいじったことがありませんが、ネットワークなどの非同期処理一般に言えることは
Swift
1 db.collection("aaa").document("bbb").collection("ccc").getDocuments() { (querySnapshot, err) in
上記の文のクロージャは、非同期で処理されています。
つまり、
Swift
1 // (1)
2 getDocuments()
3
4 // (2)
5 // division & to String
6 self.doneRateNumber.text = "(round( amountNumber / aNumber * 100))"
とした場合、(1)
で処理を実行しても、(2)
に到達する前に処理が完了している保証はありません。
言い方を変えれば、 クロージャで処理しているamountNumber
(クロージャ内部だとself.amountNumber
)に値が代入される前に (2)
に到達することが十分にあり得るということです。
したがって、ラベルに値を反映させる処理もクロージャ内部に記述するか、あるいはgetDocuments()
が処理完了後のクロージャなどを引数として取るようなメソッドとし、内部で渡されたクロージャの処理を任意のタイミングで行う、という方針を取ることとなります。
かなり抽象的なコードですが、たとえばこのような感じになるかと思います。
Swift
1// ここでは引数を1つ取り、戻り値を持たないクロージャを仮定。もちろん必要に応じて引数の個数や型を変更する
2func getDocuments(completion: @escaping (String) -> () ){
3 // クロージャに渡したいデータ
4 let data = "done"
5
6 // 遅延の処理の代わりに DispatchQueue を使って1秒後に処理を行なっている。
7 DispatchQueue.main.asyncAfter(deadline: .now() + 1.0 ){
8 // クロージャに処理を行わせる
9 completion(data)
10 }
11
12 // 実際には次のようなパターンを採用する(これ以外もあり得る)
13
14 // (1)UI部品の更新を行わない場合
15 // completion(data)
16
17 // (2) クロージャ でUI部品の更新を行う(可能性がある)場合にはメインキューに入れて処理を行う
18 // DispatchQueue.main.async {
19 // completion(data)
20 //}
21
22}
23
24getDocuments() { data in
25 // クロージャで処理したデータは data に入ってくる。
26
27 // 実際にはラベルの更新などを行う
28 // label.text = text
29 print(data)
30}
31
詳細が分からないので間違っている可能性もありますが、実際のコードに反映させるならこのような感じとなります。
Swift
1func getDocuments(completion: @escaping (Int) -> () ){
2 let db = Firestore.firestore()
3 db.collection("aaa").document("bbb").collection("ccc").getDocuments() { (querySnapshot, err) in
4 if let err = err {
5 print("Error getting documents: (err)")
6 } else {
7 for document in querySnapshot!.documents {
8 if let count = querySnapshot?.documents.count {
9 DispatchQueue.main.async {
10 completion(count)
11 }
12 }
13 }
14 }
15 }
16}
17
18...
19
20override func viewDidLoad() {
21 super.viewDidLoad()
22
23 getDocuments() { count in
24 self.aNumber = Double(count)
25 self.amountNumber.text = "(count)" // 20
26 print(self.aNumber)
27 }
28}
##2020年9月1日追記
1引数のクロージャには、下記のように他にもいくつかの書き方がありますので、わかりやすい方法を使っていただければと思います。
Swift
1getDocuments { data in
2 print(data)
3}
4
5getDocuments(completion: { data in
6 print(data)
7})
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/08/31 17:10
2020/09/01 04:33 編集
2020/09/01 04:29