热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Firebase检索数据-无法转换值-FirebaseRetrieveData-Couldnotcastvalue

First,Ihavecheckedtheseanswersthatdonothelpme:SwiftJSONerror,Couldnotcastvalueof

First, I have checked these answers that do not help me : Swift JSON error, Could not cast value of type '__NSArrayM' (0x507b58) to 'NSDictionary' (0x507d74)

首先,我已经检查了这些答案,不帮我:斯威夫特JSON错误,无法投类型的值“__NSArrayM”(0x507b58)为“NSDictionary中”(0x507d74)

Get data from Firebase

从Firebase获取数据

When retrieving data from Firebase (3.x), I have an error that occurs which is :

从Firebase(3.x)检索数据时,出现错误,即:

Could not cast value of type '__NSArrayM' (0x10ca9fc30) to 'NSDictionary' (0x10caa0108).

with this code and tree :

使用此代码和树:

Tree :

enter image description here

Retrieving 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 - To manage the data

Planes.swift - 管理数据

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
    }

on the line : let snapshotValue = snapshot.value as! [String:AnyObject]

在线:让snapshotValue = snapshot.value为! [字符串:AnyObject]

I suppose that is due to the snapshot value that can't be retrieved under [String:AnyObject] because of the Int below. (It is working when I only have String in another case).

我想这是由于在[String:AnyObject]下无法检索的快照值,因为下面的Int。 (当我在另一个案例中只有String时,它正在工作)。

I also know that Firebase "converts" the JSON tree to these objects [link]:

我也知道Firebase将JSON树“转换”为这些对象[link]:

  • NSString
  • NSNumber
  • NSArray
  • NSDictionnary

but I can't figure out what has to be changed in the snapshot.value line to make it work.

但我无法弄清楚snapshot.value行中需要更改的内容才能使其正常工作。

Thanks for your help.

谢谢你的帮助。

EDIT : I just sent a troubleshooting request. Will post updates. EDIT 2: See Jay's answer. In my case the tree was wrong.

编辑:我刚刚发送了一个故障排除请求。将发布更新。编辑2:看杰伊的答案。在我的情况下,树是错的。

4 个解决方案

#1


2  

I took your code and shrunk it down a bit for testing, and it's working. (note Firebase 2.x on OS X and Swift 3 but the code is similar)

我拿了你的代码并将其缩小了一点以进行测试,并且它正在工作。 (注意OS X和Swift 3上的Firebase 2.x,但代码类似)

Firebase structure:

  "what-am" : {
    "results" : [ {
      "code" : "738/B738",
      "data" : "Boeing",
      "engines" : "Rolls"
    }, {
      "code" : "727/B727",
      "data" : "Boeing",
      "engines" : "Pratt"
    } ]
  }

Here's the Planes struct

这是Planes结构

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
    }
}

and then the code that reads in two planes, populates and array and then prints the array.

然后读入两个平面的代码,填充和数组,然后打印数组。

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)

        }
})

and finally the output

最后输出

[Swift_Firebase_Test.Planes(code: 738/B738, data: Boeing, engines: Rolls),
 Swift_Firebase_Test.Planes(code: 727/B727, data: Boeing, engines: Pratt)]

Key and name are nil as I removed then from the Planes structure.

当我从Planes结构中移除时,键和名称为nil。

The line you asked about

你问过的那条线

let snapshotValue = snapshot.value as! [String:AnyObject]

is valid as the snapshot contains a series of key:value pairs so String:AnyObject works.

有效,因为快照包含一系列键:值对,因此String:AnyObject有效。

This line changed due to Swift 3

由于Swift 3,此行已更改

for item in (snapshot?.children)!

but other than that, the code works.

但除此之外,代码有效。

Try this to ensure you are reading the correct node. This reads the above structure and prints out each engine type. (tested and works)

试试这个以确保您正在读取正确的节点。这将读取上述结构并打印出每种引擎类型。 (测试和工作)

 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!)
           }    
      }
 })

#2


0  

I think you are having an extra array in your results key-value on the firebase data.

我认为你在firebase数据的结果键值中有一个额外的数组。

  • You should try removing that array or

    你应该尝试删除该数组或

  • You may retrieve dictionary from first index of the array like;

    您可以从数组的第一个索引中检索字典,如:

    // .. your code
    let snapshotValue = (snapshot.value as! [AnyObject])[0] as! [String:AnyObject];
    // .. your code
    

#3


0  

In your struct class make sure of these things:-

在你的struct类中确保这些东西: -

  • Avoid declaring your variables as :Int? because that's practically nil, change them to :Int!

    避免将变量声明为:Int?因为那几乎是零,所以改为:Int!

  • Your key in your firebase is an Int and you are declaring your key in struct as let key: String!, Change it to let key: Int!

    你的firebase中的密钥是一个Int,你在struct中声明你的密钥,因为let:String !,把它更改为let key:Int!

  • Prefer your snapshot dictionary declaration as let snapshotValue = snapshot.value as! [AnyHashable:Any] (as per swift 3)

    首选快照字典声明,因为snapshotValue = snapshot.value为! [AnyHashable:Any](根据swift 3)

Then your init function to :-

然后你的init函数: -

Just change the line

只需改变线条

let snapshotValue = snapshot.value as! [String:AnyObject]

To

let snapshotValue = (snapshot.value as! NSArray)[0] as! [String:AnyObject]

#4


0  

update FIRDataSnapshot to DataSnapshot Swift 4

将FIRDataSnapshot更新为DataSnapshot Swift 4


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 本文介绍了利用ARMA模型对平稳非白噪声序列进行建模的步骤及代码实现。首先对观察值序列进行样本自相关系数和样本偏自相关系数的计算,然后根据这些系数的性质选择适当的ARMA模型进行拟合,并估计模型中的位置参数。接着进行模型的有效性检验,如果不通过则重新选择模型再拟合,如果通过则进行模型优化。最后利用拟合模型预测序列的未来走势。文章还介绍了绘制时序图、平稳性检验、白噪声检验、确定ARMA阶数和预测未来走势的代码实现。 ... [详细]
  • 【Mysql】九、Mysql高级篇 索引
    MYSQL索引一、什么是索引?二、索引数据结构1、mysql数据库的四种索引2、BTREE结构三、索引分类、创建索引、查看索引1、单值索引2、复合索引3、函数索引4、 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
  • 本文介绍了如何在Mac上使用Pillow库加载不同于默认字体和大小的字体,并提供了一个简单的示例代码。通过该示例,读者可以了解如何在Python中使用Pillow库来写入不同字体的文本。同时,本文也解决了在Mac上使用Pillow库加载字体时可能遇到的问题。读者可以根据本文提供的示例代码,轻松实现在Mac上使用Pillow库加载不同字体的功能。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • Explain如何助力SQL语句的优化及其分析方法
    本文介绍了Explain如何助力SQL语句的优化以及分析方法。Explain是一个数据库SQL语句的模拟器,通过对SQL语句的模拟返回一个性能分析表,从而帮助工程师了解程序运行缓慢的原因。文章还介绍了Explain运行方法以及如何分析Explain表格中各个字段的含义。MySQL 5.5开始支持Explain功能,但仅限于select语句,而MySQL 5.7逐渐支持对update、delete和insert语句的模拟和分析。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • 本文主要介绍了gym102222KVertex Covers(高维前缀和,meet in the middle)相关的知识,包括题意、思路和解题代码。题目给定一张n点m边的图,点带点权,定义点覆盖的权值为点权之积,要求所有点覆盖的权值之和膜qn小于等于36。文章详细介绍了解题思路,通过将图分成两个点数接近的点集L和R,并分别枚举子集S和T,判断S和T能否覆盖所有内部的边。文章还提到了使用位运算加速判断覆盖和推导T'的方法。最后给出了解题的代码。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了源码分析--ConcurrentHashMap与HashTable(JDK1.8)相关的知识,希望对你有一定的参考价值。  Concu ... [详细]
  • 学习笔记17:Opencv处理调整图片亮度和对比度
    一、理论基础在数学中我们学过线性理论,在图像亮度和对比度调节中同样适用,看下面这个公式:在图像像素中其中:参数f(x)表示源图像像素。参数g(x)表示输出图像像素。 ... [详细]
author-avatar
Sn_杀手_451
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有