【问题标题】:Swift - How to write complex objects to Firebase realtime databaseSwift - 如何将复杂对象写入 Firebase 实时数据库
【发布时间】:2020-08-15 14:28:30
【问题描述】:

我是 Firebase 实时数据库的新手,对 Swift 来说总体来说还是比较陌生的。我正在尝试构建一个歌曲请求应用程序,用户可以在其中为客人创建事件以从 Spotify API 请求歌曲。我正在尝试将 Event 对象写入 Firebase,其中包含嵌套对象和不同类型的数组。但是,当它写入数据库时​​,它只写入字符串,而不写入数组或对象。将所有这些信息以嵌套结构写入 Firebase 数据库的最佳方式是什么,这样每当用户添加歌曲请求时,我都可以在 firebase 中编辑给定事件的请求数组。

这是我的代码:

Event.swift

struct Event: Codable{

    var code: String
    var name: String
    var host: String
    var description: String
    var hostUserId: String
    var guestIds: [String]
    var requests: [Request]
    var queue: [Request]
    var played: [Request]
    //private var allowExplicit: Bool
    //private var eventLocation

    init(code: String, name: String, host: String, description: String, hostUserId: String){
        self.code = code
        self.name = name
        self.host = host
        self.description = description
        self.hostUserId = hostUserId
        self.guestIds = []
        self.requests = []
        self.queue = []
        self.played = []
    }

    func toAnyObject() -> Any{
        var guestIdsDict: [String:String] = [:]
        for id in guestIds{
            guestIdsDict[id] = id
        }
    
        var requestsDict: [String: Any] = [:]
        for request in requests{
            requestsDict[request.getId()] = request.toAnyObject()
        }
    
        var queueDict: [String: Any] = [:]
        for request in queue{
            queueDict[request.getId()] = request.toAnyObject()
        }
    
        var playedDict: [String: Any] = [:]
        for request in played{
            playedDict[request.getId()] = request.toAnyObject()
        }
    
        return [
            "code": code,
            "name": name,
            "host": host,
            "description": description,
            "hostUserId": hostUserId,
            "guestIds": guestIdsDict,
            "requests": requestsDict,
            "queue":queueDict,
            "played":playedDict
        ]
    }
}

Request.swift

struct Request: Codable{
    private var name: String
    private var id: String
    private var explicit: Bool
    private var album: Album
    private var artists: [Artist]
    private var likes: Int

    init(name: String, id: String, explicit: Bool, album: Album, artists: [Artist]){
        self.name = name
        self.id = id
        self.explicit = explicit
        self.album = album
        self.artists = artists
        self.likes = 1
    }

    func toAnyObject() -> Any{
        var artistsDict: [String:Any] = [:]
        for artist in artists {
            artistsDict[artist.id] = artist.toAnyObject()
        }
        return [
            "name": name,
            "id": id,
            "explicit": explicit,
            "album": album.toAnyObject(),
            "artists": artistsDict,
            "likes": likes
        ]
    }

    mutating func like(){
        self.likes += 1
    }

    mutating func unlike(){
        self.likes -= 1
        if(self.likes < 0){
            self.likes = 0
        }
    }

    mutating func setLikes(count: Int){
        self.likes = count
    }

    func getLikes() -> Int{
        return self.likes
    }

    func getName() -> String{
        return self.name
    }

    func getId() -> String{
        return self.id
    }

    func getExplicit() -> Bool{
        return self.explicit
    }

    func getAlbum() -> Album {
        return self.album
    }

    func getImages() -> [Image] {
        return self.album.images
    }

    func getArtists() -> [Artist] {
        return self.artists
    }

    func getArtistString() -> String{
        var artistString = ""
        for (i, artist) in self.artists.enumerated(){
            artistString += artist.name
            if(i != self.artists.endIndex-1){
                artistString += ", "
            }
        }
        return artistString
    }
}

专辑.swift

struct Album: Codable{
    let name: String
    let images: [Image]

    func toAnyObject() -> Any{
        var imagesDict: [String: Any] = [:]
        for image in images{
            imagesDict[image.url] = image.toAnyObject()
        }
        return [
            "name": name,
            "images": imagesDict
        ]
    }
}

艺术家.swift

struct Artist: Codable{
    let id: String
    let name: String

    func toAnyObject() -> Any{
        return ["id": id, "name": name]
    }
}

Image.swift

struct Image: Codable{
    let height: Int
    let url: String
    let width: Int

    func toAnyObject() -> Any{
        return ["height": height, "url": url, "width": width]
    }
}

【问题讨论】:

    标签: ios swift firebase dictionary firebase-realtime-database


    【解决方案1】:

    当您使用 Codable 时,您可以使用它创建一个 dic,如下所示:

    第 1 步:将此扩展添加到您的代码中

    extension Encodable {
      var dictionary: [String: Any]? {
        guard let data = try? JSONEncoder().encode(self) else { return nil }
        return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)).flatMap { $0 as? [String: Any] }
      }
    }
    

    第 2 步:在 Struct 中编写以下代码(您必须在每个结构中执行此操作,或者您可以根据需要修改代码)。

    func createDic() -> [String: Any]? {
        guard let dic = self.dictionary else {
            return nil
        }
        
        return dic
    }
    

    现在在struct obj的帮助下,调用createDic()方法,你会得到一个字典。

    您可以将此字典发送到 firebase。

    完整代码示例:

    extension Encodable {
          var dictionary: [String: Any]? {
          guard let data = try? JSONEncoder().encode(self) else { return nil }
    }
    
    struct LoginModel: Codable {
        let email: String
        let password: String
        
        func createDic() -> [String: Any]? {
            guard let dic = self.dictionary else {
                return nil
            }
            
            return dic
        }
    }
    

    如果您有任何问题,请发表评论。

    乐于助人!

    【讨论】:

    • 感谢您的帮助和快速响应!这完全符合我的预期。
    • 太棒了!!!快乐编码。当您能够这样做时,请不要忘记投票。谢谢
    • @MohitKumar 你能看看这个问题并提供你的建议吗? stackoverflow.com/questions/63911991/…
    • @MohitKumar 对不起,我完全不明白..你能举例说明如何实施你的解决方案吗!?
    • @Learn2Code 示例已添加。如果这能解决您的问题,请告诉我。
    猜你喜欢
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    相关资源
    最近更新 更多