ios - Swift/Firebase - 无法检索输入的数据?

标签 ios json swift firebase

按照输入顺序从 Firebase 检索数据时出现问题。我已经尝试了多种方法,使用 .valueAdded 和 .value 的不同变体以相同的顺序返回,但没有运气。也许我对这些数据建模的方式不正确?对此的任何帮助都会很棒。谢谢。

这是我的 Firebase 结构:

enter image description here

这是我的数据模型:

结构 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。当我将其他变量的数据添加到此输出时,由于某种原因,它们都变得混合起来。

enter image description here

这是将数据发送到 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 不保证解释值的顺序。您必须自己对值进行排序,或者更新设备端的缓存,并在每次更新时对该缓存进行排序。

对于不同的用例,有很多简单或复杂的方法。但是看看你的,在你调用 delegatedatasource 方法之前,我会在你读取 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/

相关文章:

ios - 将 CameraView 中的图像与叠加相结合。 ( swift 3)?

ios - Xcode 8.2 : UIPageViewControllerDatasource method broken

ios - SlideMenu 可在 iOS 内部屏幕上访问

java - Java 对象中的 JSON 值

ios - Swift 4 中的文本到语音转换

ios - 在文本字段中自动添加连字符但无法编辑文本字段(电话号码屏蔽)

javascript - jquery append() 正在创建两个 div 元素

python - 在flask html页面中访问json数据

ios - 检查 viewDidLoad 上的 UITextField 是否为空并启用按钮

html - Swift - multipart/form-data - 如何定义边界/填充 HTML 正文?