Firebase JSON反序列化Swift [英] firebase json deserialization swift

本文介绍了Firebase JSON反序列化Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有需要在字典中输入的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"
    }
},

回顾一下,房间是房间的数组,房间是特定房间的对象,成员是用户的数组,成员是特定的用户.

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

来自FireBase的

snapshot.value:

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";
    };
})

这种格式不适用于字典,我相信这是因为有密钥,但是我不知道如何摆脱它,因为从本质上讲,这就是我分离Members数组中每个成员的方式.

有什么建议吗?

关于liveCell的屏幕截图很好地说明了它...

这是一个liveCell,您可以看到数据匹配的位置.黄色矩形是另一个uicollection视图,其中包含成员个人档案图像数组,其中每个个人档案图像将位于红色正方形内.

希望这可以清除一切

解决方案

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

赋予与您相似的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

I have JSON data I need entered in a dictionary and then appended to an array.

Below is where that should take place, but I get the error

this class is not key value coding-compliant for the key K0tA3yTnxAWxCFBZoeyAjcr3yYy1.'

let room = rooms[indexPath.row]

if let dictionary = room.members {

    let user = User()

    user.setValuesForKeys(dictionary)

    liveCell.members.append(user)

}

Below are the classes

User

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

Room

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

Room object in database

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

To recap, rooms is an array of rooms, room is the specific room object, members is an array of users, and member is the specific user.

I have used the dictionary method already to retrieve users from my database, but I found some differences between the datasnapshots.

snapshot.value from FireBase:

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

This format works for the dictionary

data snapshot using print(room.members):

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

This format doesn't work for the dictionary I believe it's because of the key but I don't know how to get rid of it because that is essentially how I separate each member in the members array.

Any suggestions?

As for what liveCell is here is a screen shot that explains it well...

This is a liveCell and you can see where the data matches up. The yellow rectangle is another uicollectionview that houses the array of members profileimages in which each profile image will be inside the red square.

Hope this clears things up

解决方案

Instead of trying to fix all of that code, here's a clean, simple way to populate an array of rooms, where each room has an array of users.

Given a Firebase Structure similar to yours

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

We start off with the RoomClass and UserClass. Note that I make those classes do the heavy lifting - they tear down the snapshot and store it's values.

Note that I treat the members child node as a snapshot so I can iterate over it while maintaining it's key: value pairs.

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

We then define the array to store the rooms and the code to populate it

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

and the output

Test123
  Barry
  Maurice
  Robin

这篇关于Firebase JSON反序列化Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆