Firebase iOS Swift fatal error: NSArray element failed to match the Swift Array Element type

时光毁灭记忆、已成空白 提交于 2019-12-23 05:00:32

问题


I am trying to fetch data from firebase database the format of data is below.

{
  "chits": {
    "Chit-1": {
      "Bidders": [
        {
          "bankAccNumber": "5555566966",
          "bankIFSC": "GFHJJHHJ",
          "bankName": "55666",
          "bidderEmail": "desi@venkat.co.in",
          "bidderId": "Bidder-1",
          "bidderName": "Venkat Desi",
          "bidderPhone": "9999999999",
          "checked": false,
          "paymentType": 66555
        },
        {
          "bankAccNumber": "5555566966",
          "bankIFSC": "GFHJJHHJ",
          "bankName": "55666",
          "bidderEmail": "desi@venkat.co.in",
          "bidderId": "Bidder-2",
          "bidderName": "Venkat Desi",
          "bidderPhone": "9999999999",
          "checked": false,
          "paymentType": 66555
        }
      ],
      "chitId": "Chit-1",
      "chitName": "ABC1",
      "chitTotalValue": 240000,
      "endDate": "11/10/2018",
      "monthlyShare": 1000,
      "startDate": "11/10/2017",
      "totalMonths": 12
    }
  }
}

According to the above JSON, I have created models

Bidder.swift

    class Bidder {

    var bidderId: Int
    var bidderName: String
    var bidderEmail: String
    var bidderPhone : String
    var modeOfPayment: Int
    var bidderBankName: String
    var bidderBankAcno: String
    var bidderIfscCode: String
    var paymentArray : [[String:String]]?
    var chitrefArray : [String]?
    var ref: FIRDatabaseReference?

    init(bidderId: Int, bidderName: String,bidderEmail: String, bidderPhone: String, modeOfPayment: Int, bidderBankName: String, bidderBankAcno: String, bidderIfscCode: String,paymentArray:  [[String:String]], chitrefArray: [String]) {
        self.bidderId = bidderId
        self.bidderName = bidderName
        self.bidderEmail = bidderEmail
        self.bidderPhone = bidderPhone
        self.modeOfPayment = modeOfPayment
        self.bidderBankName = bidderBankName
        self.bidderBankAcno = bidderBankAcno
        self.bidderIfscCode = bidderIfscCode
        self.paymentArray = paymentArray
        self.chitrefArray = chitrefArray
        self.ref = nil
    }

    init(snapshot: FIRDataSnapshot) {
        let snapshotValue = snapshot.value as! [String: AnyObject]
        bidderId = snapshotValue["bidderId"] as! Int
        bidderName = snapshotValue["bidderName"] as! String
        bidderEmail = snapshotValue["bidderEmail"] as! String
        bidderPhone = snapshotValue["bidderPhone"] as! String
        modeOfPayment = snapshotValue["modeOfPayment"] as! Int
        bidderBankName = snapshotValue["bidderBankName"] as! String
        bidderBankAcno = snapshotValue["bidderBankAcno"] as! String
        bidderIfscCode = snapshotValue["bidderIfscCode"] as! String
        paymentArray = snapshotValue["paymentArray"] as? [[String : String]]
        chitrefArray = snapshotValue["chitrefArray"] as? [String]
        ref = snapshot.ref
    }

    func toAnyObject() -> Any {
        return [
            "bidderId" : bidderId,
            "bidderName" : bidderName,
            "bidderEmail": bidderEmail,
            "bidderPhone": bidderPhone,
            "modeOfPayment": modeOfPayment,
            "bidderBankName":bidderBankName,
            "bidderBankAcno": bidderBankAcno,
            "bidderIfscCode":bidderIfscCode,
            "paymentArray": paymentArray as Any,
            "chitrefArray" : chitrefArray as Any
        ]
    }

}

ChitObject.swift

class ChitObject {

    var chitId : Int
    var chitName: String
    var startDate: String
    var endDate : String
    var chitTotalAmt: Int
    var chitTotalMonths: Int
    var bidders: [Bidder]
    var ref: FIRDatabaseReference?

    init(chitId: Int,chitName: String, startDate: String, endDate: String, chitTotalAmt: Int, chitTotalMonths: Int, bidders: [Bidder]) {
        self.chitId = chitId
        self.chitName = chitName
        self.startDate = startDate
        self.endDate = endDate
        self.chitTotalAmt = chitTotalAmt
        self.chitTotalMonths = chitTotalMonths
        self.bidders = bidders 
        self.ref = nil
    }

    init(snapshot: FIRDataSnapshot) {
        let snapshotValue = snapshot.value as! [String: AnyObject]
        chitId = snapshotValue["chitId"] as! Int
        chitName = snapshotValue["chitName"] as! String
        startDate = snapshotValue["startDate"] as! String
        endDate = snapshotValue["endDate"] as! String
        chitTotalAmt = snapshotValue["chitTotalAmt"] as! Int
        chitTotalMonths = snapshotValue["chitTotalMonths"] as! Int
        bidders = snapshotValue["bidders"] as! [Bidder]
        ref = snapshot.ref
    }

    func toAnyObject() -> Dictionary<String, Any>
    {
        return [
            "chitId" : chitId,
            "chitName": chitName,
            "startDate": startDate,
            "endDate": endDate,
            "chitTotalAmt":chitTotalAmt,
            "chitTotalMonths": chitTotalMonths,
            "bidders":bidders.map({$0.toAnyObject()})
        ]
    }

}

However, In Viewcontroller I am trying to fetch the biddersList from the code below.

var chitsArray = [ChitObject]()
 ChitUtils.chitRef.queryOrdered(byChild: "chitId").observe(.value, with: { snapshot in
            if snapshot.childrenCount > 0
            {
                self.chitsArray.removeAll()
                for item in snapshot.children
                {
                    let chitItem = ChitObject(snapshot: item as! FIRDataSnapshot)
                    self.chitsArray.append(chitItem)
                }
                    self.chitsArray = self.chitsArray.reversed()
                    print(self.chitsArray.first!.bidders)
                    ChitUtils.lastChitId = (self.chitsArray.first?.chitId)! + 1
                    self.chitsTableView.reloadData()
            }
        })

The fatal error only occurs while trying to access bidders array at print(self.chitsArray.first!.bidders). But, the array count seems to be correct all the time.


回答1:


The issue is in your ChitObject class, specifially here:

bidders = snapshotValue["bidders"] as! [Bidder]

You would need to create an array of Bidders and assign that into bidders variable. Loop through the array you get from snapshotValue["bidders"] and create Bidders object for every value and assign that into a Swift array.

I have not workded with Firebase but something like this may work:

init(snapshot: FIRDataSnapshot) {
    let snapshotValue = snapshot.value as! [String: AnyObject]
    chitId = snapshotValue["chitId"] as! Int
    chitName = snapshotValue["chitName"] as! String
    startDate = snapshotValue["startDate"] as! String
    endDate = snapshotValue["endDate"] as! String
    chitTotalAmt = snapshotValue["chitTotalAmt"] as! Int
    chitTotalMonths = snapshotValue["chitTotalMonths"] as! Int
    if let biddersArray = snapshotValue["bidders"] as? [[String:Any]] {
        bidders = biddersArray.flatMap{Bidder(dict:$0)}
    }
    ref = snapshot.ref
}

EDITED:

class Bidder {

    var bidderId: Int
    var bidderName: String
    var bidderEmail: String
    var bidderPhone : String
    var modeOfPayment: Int
    var bidderBankName: String
    var bidderBankAcno: String
    var bidderIfscCode: String
    var paymentArray : [[String:String]]?
    var chitrefArray : [String]?
    var ref: FIRDatabaseReference?

    convenience init?(dict:[String:Any]) {
        guard let bidderId = dict["bidderId"] as? Int, let bidderName = dict["bidderName"] as? String, let bidderEmail = dict["bidderEmail"] as? String, let bidderPhone = dict["bidderPhone"] as? String, let modeOfPayment = dict["paymentType"] as? Int, let bidderBankName = dict["bankName"] as? String, let bidderBankAcno = dict["bankAccNumber"] as? String, let bidderIfscCode = dict["bankIFSC"] as? String else {
            return nil
        }
        self.init(bidderId: bidderId, bidderName: bidderName, bidderEmail: bidderEmail, bidderPhone: bidderPhone, modeOfPayment: modeOfPayment, bidderBankName: bidderBankName, bidderBankAcno: bidderBankAcno, bidderIfscCode: bidderIfscCode, paymentArray: [[]], chitrefArray: [])
    }

    init(bidderId: Int, bidderName: String,bidderEmail: String, bidderPhone: String, modeOfPayment: Int, bidderBankName: String, bidderBankAcno: String, bidderIfscCode: String,paymentArray:  [[String:String]], chitrefArray: [String]) {
        self.bidderId = bidderId
        self.bidderName = bidderName
        self.bidderEmail = bidderEmail
        self.bidderPhone = bidderPhone
        self.modeOfPayment = modeOfPayment
        self.bidderBankName = bidderBankName
        self.bidderBankAcno = bidderBankAcno
        self.bidderIfscCode = bidderIfscCode
        self.paymentArray = paymentArray
        self.chitrefArray = chitrefArray
        self.ref = nil
    }

    init(snapshot: FIRDataSnapshot) {
        let snapshotValue = snapshot.value as! [String: AnyObject]
        bidderId = snapshotValue["bidderId"] as! Int
        bidderName = snapshotValue["bidderName"] as! String
        bidderEmail = snapshotValue["bidderEmail"] as! String
        bidderPhone = snapshotValue["bidderPhone"] as! String
        modeOfPayment = snapshotValue["modeOfPayment"] as! Int
        bidderBankName = snapshotValue["bidderBankName"] as! String
        bidderBankAcno = snapshotValue["bidderBankAcno"] as! String
        bidderIfscCode = snapshotValue["bidderIfscCode"] as! String
        paymentArray = snapshotValue["paymentArray"] as? [[String : String]]
        chitrefArray = snapshotValue["chitrefArray"] as? [String]
        ref = snapshot.ref
    }

    func toAnyObject() -> Any {
        return [
            "bidderId" : bidderId,
            "bidderName" : bidderName,
            "bidderEmail": bidderEmail,
            "bidderPhone": bidderPhone,
            "modeOfPayment": modeOfPayment,
            "bidderBankName":bidderBankName,
            "bidderBankAcno": bidderBankAcno,
            "bidderIfscCode":bidderIfscCode,
            "paymentArray": paymentArray as Any,
            "chitrefArray" : chitrefArray as Any
        ]
    }

}


来源:https://stackoverflow.com/questions/46728470/firebase-ios-swift-fatal-error-nsarray-element-failed-to-match-the-swift-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!