将 Firestore 数据分配给自定义对象
Assigning firestore data to custom object
我正在尝试制作一个使用 Firestore 来存储客户特定规格的应用。我有一个目前只有几个属性的 spec 对象,但我需要获取数据并将其分配给一个新的 Spec 对象,然后将其附加到一个数组以显示在 tableView 上。我不明白如何访问数组中的各个映射以将值分配给规范的每个 属性。我目前将它设置为在控制台中打印,因为每次我尝试从文档中分配一个值时它都是 nil。本质上,我需要在客户下存储数据(所有客户的总列表),在其他数据中有一个规格数组,其中包含每个客户的 specNumber、specDescription 和 palletCount。
示例:
Customer: Test
Specs:
3096:
Description: 50#top
pltCount: 250
3097:
Description: 50#bottom
pltCount: 250
Firestore 数据:
enter image description here
代码:
let settings = FirestoreSettings()
Firestore.firestore().settings = settings
db = Firestore.firestore()
db.collection("customers/test/specs")//.whereField("isCustomer", isEqualTo: true)
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
规范调用代码:
struct Spec {
// Properties
var specNumber: String
var specDescription: String
var palletCount: Int
//var palletsOrdered = 0
init(specNum: Int, specDesc: String, pltCount: Int) {
specNumber = "\(specNum)"
specDescription = specDesc
palletCount = pltCount
}
}
您必须将对文档的访问与对文档中数据的访问分开(您尝试同时进行)。您不能在文档或文档中的字段上调用 getDocuments()
,只能在集合上调用。因此,请尝试使用
而不是 db.collection("customers/test/specs").getDocuments()
db.collection("customers").getDocuments() { (snapshot, error) in ... }
然后从文档中获取数据:
db.collection("customers").getDocuments() { (snapshot, error) in
if let snapshot = snapshot { // lead by unwrapping the snapshot instead of the error
for doc in snapshot.documents { // iterate through the documents
guard let specs = doc.get("specs") as? [[String: Any]] else {
continue // continue loop
}
for s in specs { // iterate through the array of specs
if let specNum = s["SpecNum"] as? String,
let specDesc = s["SpecDesc"] as? String,
let pltCount = s["PalletCount"] as? Int {
let spec = Spec(specNum: specNum, specDesc: specDesc, pltCount: pltCount)
self.someArray.append(spec)
}
}
self.tableView.reloadData() // loop is done, reload
}
} else {
if let error = error {
print(error)
}
}
}
这是我想象中您实际想要实现它的方式的一个非常简化的版本,具体取决于 table/collection 的重新加载方式(即时、定期或仅一次)。此外,每个文档都包含一个规格数组,但您要从集合中获取所有文档,这会为您提供大量规格,而没有任何迹象表明哪个规格与哪个客户相关联。但我怀疑这只是早期设置,您只是想先了解 API。
注意:Firestore 中的地图在 Swift 中称为字典,它们总是作为 [String: Any]
字典从 Firestore 返回。这就是为什么当我们最初展开规格图时,我们将其转换为字典数组:
let specs = doc.get("specs") as? [[String: Any]]
我正在尝试制作一个使用 Firestore 来存储客户特定规格的应用。我有一个目前只有几个属性的 spec 对象,但我需要获取数据并将其分配给一个新的 Spec 对象,然后将其附加到一个数组以显示在 tableView 上。我不明白如何访问数组中的各个映射以将值分配给规范的每个 属性。我目前将它设置为在控制台中打印,因为每次我尝试从文档中分配一个值时它都是 nil。本质上,我需要在客户下存储数据(所有客户的总列表),在其他数据中有一个规格数组,其中包含每个客户的 specNumber、specDescription 和 palletCount。
示例:
Customer: Test
Specs:
3096:
Description: 50#top
pltCount: 250
3097:
Description: 50#bottom
pltCount: 250
Firestore 数据: enter image description here
代码:
let settings = FirestoreSettings()
Firestore.firestore().settings = settings
db = Firestore.firestore()
db.collection("customers/test/specs")//.whereField("isCustomer", isEqualTo: true)
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
规范调用代码:
struct Spec {
// Properties
var specNumber: String
var specDescription: String
var palletCount: Int
//var palletsOrdered = 0
init(specNum: Int, specDesc: String, pltCount: Int) {
specNumber = "\(specNum)"
specDescription = specDesc
palletCount = pltCount
}
}
您必须将对文档的访问与对文档中数据的访问分开(您尝试同时进行)。您不能在文档或文档中的字段上调用 getDocuments()
,只能在集合上调用。因此,请尝试使用
db.collection("customers/test/specs").getDocuments()
db.collection("customers").getDocuments() { (snapshot, error) in ... }
然后从文档中获取数据:
db.collection("customers").getDocuments() { (snapshot, error) in
if let snapshot = snapshot { // lead by unwrapping the snapshot instead of the error
for doc in snapshot.documents { // iterate through the documents
guard let specs = doc.get("specs") as? [[String: Any]] else {
continue // continue loop
}
for s in specs { // iterate through the array of specs
if let specNum = s["SpecNum"] as? String,
let specDesc = s["SpecDesc"] as? String,
let pltCount = s["PalletCount"] as? Int {
let spec = Spec(specNum: specNum, specDesc: specDesc, pltCount: pltCount)
self.someArray.append(spec)
}
}
self.tableView.reloadData() // loop is done, reload
}
} else {
if let error = error {
print(error)
}
}
}
这是我想象中您实际想要实现它的方式的一个非常简化的版本,具体取决于 table/collection 的重新加载方式(即时、定期或仅一次)。此外,每个文档都包含一个规格数组,但您要从集合中获取所有文档,这会为您提供大量规格,而没有任何迹象表明哪个规格与哪个客户相关联。但我怀疑这只是早期设置,您只是想先了解 API。
注意:Firestore 中的地图在 Swift 中称为字典,它们总是作为 [String: Any]
字典从 Firestore 返回。这就是为什么当我们最初展开规格图时,我们将其转换为字典数组:
let specs = doc.get("specs") as? [[String: Any]]