按照输入顺序从 Firebase 检索数据时出现问题。我已经尝试了多种方法,使用 .valueAdded 和 .value 的不同变体以相同的顺序返回,但没有运气。也许我对这些数据建模的方式不正确?对此的任何帮助都会很棒。谢谢。
这是我的 Firebase 结构:
这是我的数据模型:
结构 RentalObjects {
var title = [String]()
var rentalType = [String]()
var dateAval = [String]()
var location = [String]()
var price = [String]()
var bond = [String]()
var pets = [String]()
var descripton = [String]()
}
这是我的表格 View VC:
导入UIKit 导入Firebase数据库
RentalTableViewVC 类:UIViewController、UITableViewDataSource、UITableViewDelegate{
@IBOutlet weak var rentalImage: UIImageView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var rentalTitle: UILabel!
@IBOutlet weak var rentalPrice: UILabel!
var rentalsObject = RentalObjects()
var databaseRef:DatabaseReference?
var handle: DatabaseHandle?
var arrayOfTitles = [String?]()
var arrayOfBond = [String?]()
var arrayOfDateAval = [String?]()
var arrayOfDes = [String?]()
var arrayOfLocation = [String?]()
var arrayOfPets = [String?]()
var arrayOfPrice = [String?]()
var arrayOfRentalType = [String?]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rentalsObject.title.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel?.text = ("Title: \(rentalsObject.title[indexPath.row]), DateAval: \(rentalsObject.dateAval[indexPath.row])")
return cell
}
@IBAction func backPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.dataSource = self
databaseRef = Database.database().reference().child("Rentals")
databaseRef?.observe(.childAdded, with: { (snapshot) in
if let dictonary = snapshot.value as? [String: AnyObject] {
print(snapshot)
switch snapshot.key {
case "bond" :
_ = dictonary.map{self.rentalsObject.bond.append(($0.value as? String)!)}
// print(self.arrayOfBond)
case "dateAval" :
_ = dictonary.map{self.rentalsObject.dateAval.append(($0.value as? String)!)}
case "description" :
_ = dictonary.map{self.rentalsObject.descripton.append(($0.value as? String)!)}
case "location" :
_ = dictonary.map{self.rentalsObject.location.append(($0.value as? String)!)}
case "pets" :
_ = dictonary.map{self.rentalsObject.pets.append(($0.value as? String)!)}
case "price" :
_ = dictonary.map{self.rentalsObject.price.append(($0.value as? String)!)}
case "rentalType" :
_ = dictonary.map{self.rentalsObject.rentalType.append(($0.value as? String)!)}
case "title" :
_ = dictonary.map{self.rentalsObject.title.append(($0.value as? String)!)}
print(self.rentalsObject.title)
// _ = dictonary.map{self.arrayOfTitles.append($0.value as? String)}
// print(self.arrayOfTitles)
default:
break
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
})
}
}
这是我的 tableView 的输出示例。我试图按照输入的顺序将其取出,在本例中为 1,2,3,4,5。当我将其他变量的数据添加到此输出时,由于某种原因,它们都变得混合起来。
这是将数据发送到 firebase 的代码:
AvertisingVC 类:UIViewController {
@IBOutlet weak var titleField: UITextField!
@IBOutlet weak var rentalTypeField: UITextField!
@IBOutlet weak var dateField: UITextField!
@IBOutlet weak var locationField: UITextField!
@IBOutlet weak var priceField: UITextField!
@IBOutlet weak var bondField: UITextField!
@IBOutlet weak var petsAllowedField: UITextField!
@IBOutlet weak var detailedDescription: UITextField!
var databaseRef:DatabaseReference? //reference to firebase dba
override func viewDidLoad() {
super.viewDidLoad()
databaseRef = Database.database().reference().child("Rentals") //can add .child(string:root) to add root dir to dba
}
@IBAction func backBtnPressed(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
@IBAction func submitForm(_ sender: Any) { // Send data to firebase on submit
if titleField.text != nil {
databaseRef?.child("title").childByAutoId().setValue(titleField.text)
titleField.text = ""
}
if rentalTypeField.text != nil {
databaseRef?.child("rentalType").childByAutoId().setValue(rentalTypeField.text)
rentalTypeField.text = ""
}
if dateField.text != nil {
databaseRef?.child("dateAval").childByAutoId().setValue(dateField.text)
dateField.text = ""
}
if locationField.text != nil {
databaseRef?.child("location").childByAutoId().setValue(locationField.text)
locationField.text = ""
}
if priceField.text != nil {
databaseRef?.child("price").childByAutoId().setValue(priceField.text)
priceField.text = ""
}
if bondField.text != nil {
databaseRef?.child("bond").childByAutoId().setValue(bondField.text)
bondField.text = ""
}
if petsAllowedField.text != nil {
databaseRef?.child("pets").childByAutoId().setValue(petsAllowedField.text)
petsAllowedField.text = ""
}
if detailedDescription.text != nil {
databaseRef?.child("description").childByAutoId().setValue(detailedDescription.text)
detailedDescription.text = ""
}
let alertController = UIAlertController(title: "Success!", message: "You have successfully listed a rental", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "Close Alert", style: .default, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
}
}
最佳答案
当从网络数据解释数据时,如果解释值在数组或字典中排序,则 swift 不保证解释值的顺序。您必须自己对值进行排序,或者更新设备端的缓存,并在每次更新时对该缓存进行排序。
对于不同的用例,有很多简单或复杂的方法。但是看看你的,在你调用 delegate
和 datasource
方法之前,我会在你读取 tableView 数据源的任何地方添加一个 sort
。以您的示例为例,如果您按日期排序:
override func viewDidLoad() {
super.viewDidLoad()
databaseRef = Database.database().reference().child("Rentals")
databaseRef?.observe(.childAdded, with: { (snapshot) in
if let dictonary = snapshot.value as? [String: AnyObject] {
print(snapshot)
switch snapshot.key {
case "bond" :
_ = dictonary.map{self.rentalsObject.bond.append(($0.value as? String)!)}
// print(self.arrayOfBond)
case "dateAval" :
_ = dictonary.map{self.rentalsObject.dateAval.append(($0.value as? String)!)}
case "description" :
_ = dictonary.map{self.rentalsObject.descripton.append(($0.value as? String)!)}
case "location" :
_ = dictonary.map{self.rentalsObject.location.append(($0.value as? String)!)}
case "pets" :
_ = dictonary.map{self.rentalsObject.pets.append(($0.value as? String)!)}
case "price" :
_ = dictonary.map{self.rentalsObject.price.append(($0.value as? String)!)}
case "rentalType" :
_ = dictonary.map{self.rentalsObject.rentalType.append(($0.value as? String)!)}
case "title" :
_ = dictonary.map{self.rentalsObject.title.append(($0.value as? String)!)}
print(self.rentalsObject.title)
// _ = dictonary.map{self.arrayOfTitles.append($0.value as? String)}
// print(self.arrayOfTitles)
default:
break
}
}
whateverCollectionIsYourInCacheDataSource = whateverCollectionIsYourInCacheDataSource.sorted(by: { ($0, $1) -> Bool in
return $0 < $1 //If you want to sort them by their date value. Make sure the dates are properly interpreted from whatever format they're saved in remotely into the Date type.
})
DispatchQueue.main.async {
//No need to call .reloadData and these methods in viewDidLoad, unless you REALLY have to (ie: your data is modified on purpose after being loaded initially). Calling these methods loads up the data anyways, so just call these whenever your data is downloaded, converted and sorted properly.
tableView.dataSource = self
tableView.dataSource = self
}
})
}
希望它能帮助您走上正确的道路。查找基于网络的 tableview/collectionview 教程,它们非常有帮助。
关于ios - Swift/Firebase - 无法检索输入的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47373269/