Firebase检索数据 – 无法投射价值
首先,我已经检查了这些不帮我的答案: Swift JSON错误,无法将types'__NSArrayM'(0x507b58)的值转换为'NSDictionary'(0x507d74)
从Firebase获取数据
从Firebase(3.x)检索数据时,发生的错误是:
Could not cast value of type '__NSArrayM' (0x10ca9fc30) to 'NSDictionary' (0x10caa0108).
用这个代码和树:
树:
检索function:
func retrievePlanes() { print("Retrieve Planes") ref = FIRDatabase.database().reference(withPath: "results") ref.observe(.value, with: { snapshot in var newItems: [Planes] = [] for item in snapshot.children { let planesItem = Planes(snapshot: item as! FIRDataSnapshot) newItems.append(planesItem) } self.planes = newItems self.tableView.reloadData() }) }
Planes.swift – pipe理数据
import Foundation import Firebase import FirebaseDatabase struct Planes { let key: String! let name: String! let code:String! let flightRange: Int? let typicalSeats: Int? let maxSeats: Int? let wingSpan: String! let takeoffLength: Int? let rateClimb: Int? let maxCruiseAltitude: Int? let cruiseSpeed: String! let landingLength: Int? let engines: String! let votes: Int? let data: String! let imagePlane:String! let imageTakenFrom: String! let ref: FIRDatabaseReference? init(name: String, code: String, flightRange: Int, typicalSeats: Int, maxSeats: Int, wingSpan: String, takeoffLength: Int, rateClimb: Int, maxCruiseAltitude: Int, cruiseSpeed: String, landingLength: Int, engines: String, votes: Int, data: String, imagePlane: String, imageTakenFrom: String, key: String = "") { self.key = key self.name = name self.code = code self.flightRange = flightRange self.typicalSeats = typicalSeats self.maxSeats = maxSeats self.wingSpan = wingSpan self.takeoffLength = takeoffLength self.rateClimb = rateClimb self.maxCruiseAltitude = maxCruiseAltitude self.cruiseSpeed = cruiseSpeed self.landingLength = landingLength self.engines = engines self.votes = votes self.data = data self.imagePlane = imagePlane self.imageTakenFrom = imageTakenFrom self.ref = nil } init(snapshot: FIRDataSnapshot) { ref = snapshot.ref key = snapshot.key let snapshotValue = snapshot.value as! [String:AnyObject] name = snapshotValue["name"] as! String code = snapshotValue["code"] as! String flightRange = snapshotValue["intFlightRange"] as? Int typicalSeats = snapshotValue["intTypicalSeats"] as? Int maxSeats = snapshotValue["intMaxSeats"] as? Int wingSpan = snapshotValue["wingSpan"] as! String takeoffLength = snapshotValue["intTakeoffLength"] as? Int rateClimb = snapshotValue["intRateClimb"] as? Int maxCruiseAltitude = snapshotValue["intMaxCruiseAltitude"] as? Int cruiseSpeed = snapshotValue["cruiseSpeed"] as! String landingLength = snapshotValue["intLandingLength"] as? Int engines = snapshotValue["engines"] as! String votes = snapshotValue["votes"] as? Int data = snapshotValue["data"] as! String imagePlane = snapshotValue["planeImage"] as! String imageTakenFrom = snapshotValue["imageTakenFrom"] as! String }
就行了: let snapshotValue = snapshot.value as! [String:AnyObject]
let snapshotValue = snapshot.value as! [String:AnyObject]
我想这是由于下面的Int
导致无法在[String:AnyObject]
下检索的快照值。 (在另一种情况下,我只有String
时正在工作)。
我也知道Firebase将JSON树“转换”为这些对象[link] :
-
NSString
-
NSNumber
-
NSArray
-
NSDictionnary
但我无法弄清楚在snapshot.value行中必须改变什么才能使其工作。
谢谢你的帮助。
编辑:我刚刚发送了一个故障排除请求。 将张贴更新。 编辑2:看杰伊的答案。 在我的情况下,树是错的。
我把你的代码缩小了一点,用于testing,它正在工作。 (请注意OS X和Swift 3上的Firebase 2.x,但代码类似)
Firebase结构:
"what-am" : { "results" : [ { "code" : "738/B738", "data" : "Boeing", "engines" : "Rolls" }, { "code" : "727/B727", "data" : "Boeing", "engines" : "Pratt" } ] }
这是平面结构
struct Planes { var code:String! var data: String! var engines: String! init(code: String, data: String, engines: String ) { self.code = code self.data = data self.engines = engines } init(snapshot: FDataSnapshot) { let snapshotValue = snapshot.value as! [String:AnyObject] code = snapshotValue["code"] as! String data = snapshotValue["data"] as! String engines = snapshotValue["engines"] as! String } }
然后读取两个平面的代码,填充和数组,然后打印数组。
let ref = self.myRootRef.child(byAppendingPath: "what-am/results")! ref.observe(.value, with: { snapshot in if ( snapshot!.value is NSNull ) { print("not found") } else { var newItems: [Planes] = [] for item in (snapshot?.children)! { let planesItem = Planes(snapshot: item as! FDataSnapshot) newItems.append(planesItem) } self.planes = newItems print(self.planes) } })
最后输出
[Swift_Firebase_Test.Planes(code: 738/B738, data: Boeing, engines: Rolls), Swift_Firebase_Test.Planes(code: 727/B727, data: Boeing, engines: Pratt)]
键和名称是零,因为我从飞机结构中删除。
你问的线
let snapshotValue = snapshot.value as! [String:AnyObject]
由于快照包含一系列键:值对,所以String:AnyObject有效。
这条线因Swift 3而改变
for item in (snapshot?.children)!
但除此之外,代码的作品。
试试这个以确保你正在阅读正确的节点。 这读取上述结构并打印出每个引擎types。 (testing和工作)
let ref = self.myRootRef.child(byAppendingPath: "what-am/results")! ref.observe(.value, with: { snapshot in if ( snapshot!.value is NSNull ) { print("not found") } else { for child in (snapshot?.children)! { let snap = child as! FDataSnapshot let dict = snap.value as! [String: String] let engines = dict["engines"] print(engines!) } } })
我想你在firebase数据的结果键值中有一个额外的数组。
-
您应该尝试删除该数组或
-
您可以从数组的第一个索引检索字典,如:
// .. your code let snapshotValue = (snapshot.value as! [AnyObject])[0] as! [String:AnyObject]; // .. your code
在你的结构类中确保这些东西:
-
避免声明你的variables为
:Int?
因为这实际上是零,改变他们:Int!
-
您的firebase中的密钥是一个Int,并且您正在声明您的密钥在结构中作为
let key: String!
,将其更改为let key: Int!
-
将您的快照字典声明视为
let snapshotValue = snapshot.value as! [AnyHashable:Any]
let snapshotValue = snapshot.value as! [AnyHashable:Any]
(按照swift 3)
然后你的init函数:
只要改变一下
let snapshotValue = snapshot.value as! [String:AnyObject]
至
let snapshotValue = (snapshot.value as! NSArray)[0] as! [String:AnyObject]