Firebase iOS Swift致命错误:NSArray元素无法与Swift数组元素类型匹配 [英] Firebase iOS Swift fatal error: NSArray element failed to match the Swift Array Element type
问题描述
{
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。投标人2,
bidderName:Venkat Desi,
bidderPhone:9999999999,
:false,
paymentType:66555
}
],
chit Id: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? (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!字符串
bidderEmail = snapshotValue [bidderEmail]为!字符串
bidderPhone = snapshotValue [bidderPhone] as!字符串
modeOfPayment = snapshotValue [modeOfPayment] as! Int
bidderBankName = snapshotValue [bidderBankName] as!字符串
bidderBankAcno = snapshotValue [bidderBankAcno] as!字符串
bidderIfscCode = snapshotValue [bidderIfscCode] as!字符串
paymentArray = snapshotValue [paymentArray] as? [[String:String]]
chitrefArray = snapshotValue [chitrefArray] as? [String]
ref = snapshot.ref
}
func toAnyObject() - >任何{
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
<$ p $ 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?
$ b $ 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!字符串
startDate = snapshotValue [startDate] as!字符串
endDate = snapshotValue [endDate] as!字符串
chitTotalAmt = snapshotValue [chitTotalAmt] as! Int
chitTotalMonths = snapshotValue [chitTotalMonths] as! Int
bidders = snapshotValue [bidders] as! [Bidder]
ref = snapshot.ref
}
func toAnyObject() - >词典< String,Any>
返回[
chitId:chitId,
chitName:chitName,
startDate:startDate,$ b $endDate:endDate ,
chitTotalAmt:chitTotalAmt,
chitTotalMonths:chitTotalMonths,
bidders:bidders.map({$ 0.toAnyObject()})
]
}
$ b
然而,在Viewcontroller中我试图获取<
$ b
var chitsArray = [ChitObject]()
ChitUtils。观察(.value,其中:$快照$ b $如果snapshot.childrenCount> 0
{
self.chitsArray.removeAll()
为snapshot.children中的项目
{
let chitItem = ChitObject(snapshot:item as!FIRDataSnapshot)
self.chitsArray.append(chi (self.chitsArray.first!.bidders)
ChitUtils.lastChitId =(self.chitsArray。())
self.chitsArray = self.chitsArray.reversed()
print第一?.chitId)! + 1
self.chitsTableView.reloadData()
}
})
仅当尝试访问 bidders array <
print(self.chitsArray.first! .bidders)。但是,阵列计数似乎一直是正确的。
问题出在您的 ChitObject $ c $特别是在这里:
bidders = snapshotValue [bidders] as! [Bidder]
您需要创建一个Bidders数组并将其分配给Bidders变量。循环访问您从snapshotValue [bidders]获得的数组,并为每个值创建Bidders对象,并将其分配到Swift数组中。
我还没有使用Firebase,这样的东西可能会工作:
$ $ p $ code init init(snapshot:FIRDataSnapshot){
let snapshotValue = snapshot.value as! [String:AnyObject]
chitId = snapshotValue [chitId] as! Int
chitName = snapshotValue [chitName] as!字符串
startDate = snapshotValue [startDate] as!字符串
endDate = snapshotValue [endDate] as!字符串
chitTotalAmt = snapshotValue [chitTotalAmt] as! Int
chitTotalMonths = snapshotValue [chitTotalMonths] as!如果让biddersArray = snapshotValue [bidders]为int
? [[String:Any]] {
bidders = biddersArray.flatMap {Bidder(dict:$ 0)}
}
ref = snapshot.ref
}
code $ <$ $ p
编辑:
类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?
便捷初始化(字符串:[String:Any]){
guard让bidderId = dict [bidderId]为?诠释,让bidderName = dict [bidderName]为?字符串,让bidderEmail = dict [bidderEmail]为?字符串,让bidderPhone = dict [bidderPhone]为?字符串,请让modeOfPayment = dict [paymentType]为?诠释,让bidderBankName = dict [bankName]为?字符串,让bidderBankAcno = dict [bankAccNumber]为?字符串,让bidderIfscCode = dict [bankIFSC]为? (bidderId:bidderId,bidderName:bidderName,bidderEmail:bidderEmail,bidderPhone:bidderPhone,modeOfPayment:modeOfPayment,bidderBankName:bidderBankName,bidderBankAcno:bidderBankAcno, bidderIfscCode:bidderIfscCode,paymentArray:[[]],chitrefArray:[])
}
(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 =支付mentArray
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!字符串
bidderEmail = snapshotValue [bidderEmail]为!字符串
bidderPhone = snapshotValue [bidderPhone] as!字符串
modeOfPayment = snapshotValue [modeOfPayment] as! Int
bidderBankName = snapshotValue [bidderBankName] as!字符串
bidderBankAcno = snapshotValue [bidderBankAcno] as!字符串
bidderIfscCode = snapshotValue [bidderIfscCode] as!字符串
paymentArray = snapshotValue [paymentArray] as? [[String:String]]
chitrefArray = snapshotValue [chitrefArray] as? [String]
ref = snapshot.ref
}
func toAnyObject() - >任何{
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
]
}
}
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.
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
]
}
}
这篇关于Firebase iOS Swift致命错误:NSArray元素无法与Swift数组元素类型匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!