【问题标题】:firebase json deserialization swiftfirebase json 反序列化 swift
【发布时间】:2017-08-03 20:43:43
【问题描述】:

我需要将 JSON 数据输入字典,然后附加到数组中。

下面是应该发生的地方,但我得到了错误

这个类不符合键的键值编码 K0tA3yTnxAWxCFBZoeyAjcr3yYy1.'

let room = rooms[indexPath.row]

if let dictionary = room.members {

    let user = User()

    user.setValuesForKeys(dictionary)

    liveCell.members.append(user)

}

以下是类

用户

class User: NSObject {
    var email: String?
    var name: String?
    var profileImageUrl: String?
}

房间

class Room: NSObject {
    var rid: String?
    var owner: String?
    var groupChatName: String?
    var groupChatDescription: String?
    var members: NSDictionary?
}

数据库中的房间对象

"rooms" : {
    "B7C7E469-945E-4327-9473-AAE34FCB9B41" : {
      "groupChatDescription" : "123ae",
      "groupChatName" : "Test123",
      "members" : {
        "K0tA3yTnxAWxCFBZoeyAjcr3yYy1" : {
          "email" : "S@gmail.com",
          "name" : "Steve",
          "profileImageUrl" : "https://firebasestorage.googleapis.com"
        }
      },
      "owner" : "Steve"
    }
},

回顾一下,rooms 是一个房间数组,room 是特定的房间对象,members 是一个用户数组,member 是特定的用户。

我已经使用字典方法从我的数据库中检索用户,但我发现数据快照之间存在一些差异。

来自 FireBase 的快照值:

Optional({
    email = "S@gmail.com";
    name = Steve;
    profileImageUrl = 
"https://firebasestorage.googleapis.com";
})

这种格式适用于字典

使用print(room.members)的数据快照:

Optional({
    K0tA3yTnxAWxCFBZoeyAjcr3yYy1 =     {
        email = "S@gmail.com";
        name = Steve;
        profileImageUrl = 
"https://firebasestorage.googleapis.com";
    };
})

这种格式不适用于字典我相信这是因为键,但我不知道如何摆脱它,因为这本质上是我如何分隔成员数组中的每个成员。

有什么建议吗?

至于这里的liveCell是什么,截图很好解释...

这是一个 liveCell,您可以看到数据匹配的位置。黄色矩形是另一个 uicollectionview,其中包含成员个人资料图像数组,其中每个个人资料图像都将位于红色方块内。

希望这能解决问题

【问题讨论】:

  • 问题中缺少一些信息(为什么 self.liveCell?有成员?),有点不清楚,members is a array of users 不清楚 - 似乎被定义为用户类中的通用字典。也许您的意思是将其定义为像 [Users] 这样的用户数组?或者它应该是一个字典?也许它是另一个数组?你能把问题清理一下吗,因为我认为答案应该很简单。
  • @Jay 我编辑了问题

标签: swift firebase-realtime-database nsdictionary firebase-storage json-deserialization


【解决方案1】:

这里不是尝试修复所有代码,而是一种干净、简单的方法来填充一组房间,其中每个房间都有一组用户。

给定一个与您类似的 Firebase 结构

  "rooms"
    "room_0"
      "groupChatName" : "Test123",
      "members"
        "user_0"
          "name" : "Barry"
        "user_1"
          "name" : "Maurice"
        "user_2"
          "name" : "Robin"

我们从 RoomClass 和 UserClass 开始。请注意,我让这些类完成繁重的工作 - 它们拆除快照并存储它的值。

请注意,我将成员子节点视为快照,因此我可以对其进行迭代,同时保持它的键:值对。

class RoomClass {
    var key = ""
    var groupChatName = ""
    var membersArray = [UserClass]()

    init(snapshot: DataSnapshot) {
        let dict = snapshot.value as! [String: Any]
        let membersSnap = snapshot.childSnapshot(forPath: "members")
        let snapKey = snapshot.key
        let groupName = dict["groupChatName"] as! String

        self.key = snapKey
        self.groupChatName = groupName

        for member in membersSnap.children {
            let memberSnap = member as! DataSnapshot
            let user = UserClass(snapshot: memberSnap)
            self.membersArray.append(user)
        }
    }
}

class UserClass {
    var key = ""
    var name = ""

    init(snapshot: DataSnapshot) {
        let dict = snapshot.value as! [String: Any]
        let snapKey = snapshot.key
        let userName = dict["name"] as! String
        self.key = snapKey
        self.name = userName
    }
}

然后我们定义数组来存储房间和填充它的代码

var roomsArray = [RoomClass]()

func doButton0Action() {
    let roomsRef = self.ref.child("rooms")
    roomsRef.observeSingleEvent(of: .value, with: { snapshot in

        for child in snapshot.children {
            let snap = child as! DataSnapshot
            let room = RoomClass(snapshot: snap)
            self.roomsArray.append(room)
        }

        //this just demonstrates the rooms and members are loaded
        for room in self.roomsArray {
            let groupChatName = room.groupChatName

            print(groupChatName)

            for user in room.membersArray {
                let userName = user.name
                print("  \(userName)")
            }
        }
    })
}

和输出

Test123
  Barry
  Maurice
  Robin

【讨论】:

  • 效果很好。谢谢。
【解决方案2】:

奇怪的解决方案,但您不应该使用 firebase 强制转换为 [String:AnyObject]。它也从来没有对我有用,但是这样做:

snapshot.value as? [String:Any]

有效。通过适当地转换snapshot.value 的可能键,添加自定义类以解释自定义用例(房间、汽车等的类等)中的快照值更多是开发人员的责任。

【讨论】:

  • 我还是不能member.setValuesForKeys(userDictionary)开火
猜你喜欢
  • 2020-10-19
  • 1970-01-01
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多