Firebase iOS Swift 致命错误:NSArray 元素无法匹配 Swift Array 元素类型
Posted
技术标签:
【中文标题】Firebase iOS Swift 致命错误:NSArray 元素无法匹配 Swift Array 元素类型【英文标题】:Firebase iOS Swift fatal error: NSArray element failed to match the Swift Array Element type 【发布时间】:2017-10-13 11:05:45 【问题描述】:我正在尝试从 firebase 数据库中获取数据,数据格式如下。
"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
根据上面的JSON,我已经创建了模型
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())
]
但是,在 Viewcontroller 中,我试图从下面的代码中获取 biddersList。
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()
)
致命错误仅在尝试访问
print(self.chitsArray.first!.bidders)
的 bidders 数组 时发生。但是,数组计数似乎一直都是正确的。
【问题讨论】:
【参考方案1】:问题出在您的 ChitObject
课程中,特别是这里:
bidders = snapshotValue["bidders"] as! [Bidder]
您需要创建一个投标人数组并将其分配给投标人变量。遍历从 snapshotValue["bidders"] 获得的数组,并为每个值创建 Bidders 对象并将其分配到 Swift 数组中。
我没有与 Firebase 合作过,但这样的事情可能会奏效:
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.flatMapBidder(dict:$0)
ref = snapshot.ref
已编辑:
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
]
【讨论】:
你的意思是说,我必须为每个项目分配每个变量?能不能发个例子,让我有个清晰的认识。 @govindkumar:编辑了答案。基本上你需要从 snapshotValue["bidders"] 中获取 Array 的值。我没有使用 Firebase,但可能是编辑作品。 If 条件总是失败导致一个空的biddersArray 在调试时,您在 snapshotValue[“bidders”] 中获得的值类型是什么? 在 Bidders 便利初始化中添加一个调试点。我猜它的失败是因为警卫条件。可能有一些不匹配或拼写错误以上是关于Firebase iOS Swift 致命错误:NSArray 元素无法匹配 Swift Array 元素类型的主要内容,如果未能解决你的问题,请参考以下文章
致命错误:索引超出范围 - Swift 3 和 Firebase
使用 Firebase 进行 iOS 开发时如何修复致命错误?