在我的应用程序中,有几个地方我正在从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
}
}
}