在我的应用程序中,有几个地方我正在从Firebase Firestore数据库加载数据并显示数据。问题是我没有采用DRY技术,我知道我不应该这样做,但是我在我的应用程序中的不同地方重用相同的加载功能。

func loadData() {

        let user = Auth.auth().currentUser
        db.collection("users").document((user?.uid)!).collection("children").getDocuments() {
            QuerySnapshot, error in
            if let error = error {
                print("\(error.localizedDescription)")
            } else {
                // get all children into an array
                self.childArray = QuerySnapshot!.documents.flatMap({Child(dictionary: $0.data())})
                DispatchQueue.main.async {
                    self.childrenTableView.reloadData()
                }
            }
        }
    }

该函数只需从数据库中获取所有子项并将它们添加到我的子数组中。
有没有更好的方法来实现这一点,或者我可以把这个函数放在一个中心位置,当我在应用程序中需要它时,就可以调用它,而不是在多个视图控制器中重复添加它?
我考虑了一个helper类,只是调用这个函数,但是不确定如何将结果添加到viewcontroller中需要的childArray中?
我的孩子模型
import UIKit
import FirebaseFirestore


protocol DocumentSerializable {
    init?(dictionary:[String:Any])
}

// Child Struct
struct Child {

    var name: String
    var age: Int
    var timestamp: Date
    var imageURL: String

    var dictionary:[String:Any] {
        return [
            "name":name,
            "age":age,
            "timestamp":timestamp,
            "imageURL":imageURL
        ]
    }

}

//Child Extension
extension Child : DocumentSerializable {
    init?(dictionary: [String : Any]) {
        guard let  name = dictionary["name"] as? String,
            let age = dictionary["age"] as? Int,
            let  imageURL = dictionary["imageURL"] as? String,
            let timestamp = dictionary["timestamp"] as? Date else {
                return nil
        }
        self.init(name: name, age: age, timestamp: timestamp, imageURL: imageURL)
    }
}

最佳答案

编辑:我已经更新以安全地打开选项。您可能仍然需要修改,因为我不确定您的Firebase结构是什么,也不知道您的子初始化器。
您可以将其作为静态函数编写,然后在任何地方重用它。我想你可能有一些与“孩子”相关的课程,这是最好的实现方式。您可以在完成处理程序中传递结果(作为Child的选项数组),以便可以对这些结果执行任何所需的操作。看起来像这样:

static func loadData(_ completion: (_ children: [Child]?)->()) {

    guard let user = Auth.auth().currentUser else { completion(nil); return }
    Firestore.firestore().collection("users").document(user.uid).collection("children").getDocuments() {
        querySnapshot, error in
        if let error = error {
            print("\(error.localizedDescription)")
            completion(nil)
        } else {
            guard let snapshot = querySnapshot else { completion(nil); return }
            // get all children into an array
            let children = snapshot.documents.flatMap({Child(dictionary: $0.data())})
            completion(children)
        }
    }
}

假设您在您的子类中实现了此功能,那么您将按如下方式使用它:
Child.loadData { (children) in
    DispatchQueue.main.async {
        if let loadedChildren = children {
            //Do whatever you need with the children
            self.childArray = loadedChildren
        }
    }
}

10-08 12:24