如何解决这个关闭完成处理程序问题?

问题描述

我已经死盯着这些函数近两天了,想知道为什么我不能得到我想要的结果。

这是第一个函数

   func getTheSchoolID(completion: @escaping ((String?)-> ())) {
    db.collection("school_users").whereField("userID",isEqualTo: user!.uid).getDocuments { (querySnapshot,err) in
        if let err = err {
            print("There was an error fetching the documents: \(err)")

        } else {
            self.skoolID = querySnapshot!.documents.map { document in
                return SchoolID(schoolID: (document.get("school_id") as! String))
            }
        }
    }

    let fixedID = "\(skoolID)"
    let substrings = fixedID.dropFirst(28).dropLast(3)
    let realString = String(substrings)
    completion(realString)

}

这是我对上一个 StackOverflow 问题的回答中的函数,所以我使用了它并了解了闭包完成处理程序的概念。

接下来的代码块是我想要发生但没有发生的。

    getTheSchoolID { [weak self] (realString) in
        if let id = realString {
            dispatchQueue.main.async {
                self?.schoolIDTextF.text = id

            }
        }
    }

现在,当我检查 Viewcontroller 中的文本字段时,它仍然是空的。

The Viewcontroller with the School ID textfield on the bottom.

收集路径很好,字段正确,我什至会添加我的 firestore 数据库的屏幕截图以供参考。

Firestore Database

如果有人能提供帮助那就太好了。如果你给我答案并且它有效,我什至会发送 10 美元的 Paypal 付款。这就是它对我的意义。谢谢。

解决方法

getDocuments 异步工作,您必须调用 completion inside 闭包

func getTheSchoolID(completion: @escaping (String?) -> Void) {
    db.collection("school_users").whereField("userID",isEqualTo: user!.uid).getDocuments { (querySnapshot,err) in
        if let err = err {
            print("There was an error fetching the documents: \(err)")
            completion(nil)
        } else {
            self.skoolID = querySnapshot!.documents.map { document in
                return SchoolID(schoolID: document.get("school_id") as! String)
            }
            let fixedID = "\(self.skoolID)"
            let substrings = fixedID.dropFirst(28).dropLast(3)
            let realString = String(substrings)
            completion(realString)
        }
    }
}

而且您使用了太多括号。

而且 map 表达式看起来很奇怪。

,

你过早地宣布关闭。您需要在 db...getDocuments 闭包内调用它,例如:

func getTheSchoolID(completion: @escaping ((String?)-> ())) {
    db.collection("school_users").whereField("userID",err) in
        if let err = err {
            print("There was an error fetching the documents: \(err)")

        } else {
            self.skoolID = querySnapshot!.documents.map { document in
                return SchoolID(schoolID: (document.get("school_id") as! String))
            }
            let fixedID = "\(skoolID)"
            let substrings = fixedID.dropFirst(28).dropLast(3)
            let realString = String(substrings)
            completion(realString)
        }
    }
}

并存钱买一本好书:-)