避免在领域数据库中的自定义对象数组中重复。仅在关系表中存在主键时

时间:2019-03-22 06:16:09

标签: ios swift realm realm-list

如何避免在领域数据库中的自定义对象数组中重复,下面是我的代码和相关的JSON。如果我在模型中做错了什么,请纠正我。

JSON->

{
  "playlists": [
    {
      "id": "1f23bd3e-cc01-11e8-b25e-784f435e4a9a",
      "name": "disney nostalgia",
      "duration": 361,
    },
    {
      "id": "2e1f0e02-cc05-11e8-9efe-784f435e4a9a",
      "name": "songs from aladdin",
      "duration": 331,
    }
  ],
    "tracks": [
        {
          "id": "3e986a2a-cc01-11e8-bb04-784f435e4a9a",
          "name": "I'll Make a Man Out of You",
          "artist": "Donny Osmond & Chorus"
        },
        {
          "id": "aff8bcee-cc04-11e8-8c18-784f435e4a9a",
          "name": "A Whole New World",
          "artist": "Lea Salonga, Brad Kane"
        }
      ]
}

和模型如下

class Songs: Object, Codable {
    let playlists = List<Playlists>()
    let tracks = List<Tracks>()
    enum CodingKeys: String, CodingKey {
        case playlists
        case tracks
    }

    required convenience public init(from decoder: Decoder) throws {
        self.init()
        let container = try decoder.container(keyedBy: CodingKeys.self)
        if let playLists = try container.decodeIfPresent([Playlists].self, forKey: .playlists){
            playLists.forEach({self.playlists.append($0)})
        }
        if let tracksList = try container.decodeIfPresent([Tracks].self, forKey: .tracks){
            tracksList.forEach({self.tracks.append($0)})
        }
    }

    func encode(to encoder: Encoder) throws {
        //
    }
}

class Playlists: Object, Codable {
    @objc dynamic var id: String = ""
    @objc dynamic var name: String = ""
    @objc dynamic var duration: Int = 0


    enum CodingKeys: String, CodingKey {
        case id
        case name
        case duration
    }

    override static func primaryKey() -> String? {
        return "id"
    }

    required convenience public init(from decoder: Decoder) throws {
        self.init()
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(String.self, forKey: .id)
        self.name = try container.decode(String.self, forKey: .name)
        self.duration = try container.decode(Int.self, forKey: .duration)
    }
}

class Tracks: Object, Codable {
    @objc dynamic var id: String = ""
    @objc dynamic var name: String = ""
    @objc dynamic var artist: Int = 0


    enum CodingKeys: String, CodingKey {
        case id
        case name
        case artist
    }

    override static func primaryKey() -> String? {
        return "id"
    }

    required convenience public init(from decoder: Decoder) throws {
        self.init()
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(String.self, forKey: .id)
        self.name = try container.decode(String.self, forKey: .name)
        self.artist = try container.decode(Int.self, forKey: .artist)
    }
}

这就是我保存数据的方式。

SongsData = try jsonDecoder.decode(Songs.self, from: data)
   let realm = try! Realm()
   try! realm.write {
          realm.add(SongsData)
    } catch {
          Logger.log.printOnConsole(string: "Unable to convert to data")
    }

服务器发出相同响应时,如何避免重复数据。

1 个答案:

答案 0 :(得分:0)

在将对象添加到Set之前,您可以只使用List来消除重复项。只要确保您的类型符合要添加到Hashable的{​​{1}}即可。

一些一般性建议:如果属性名称与JSON键匹配,则无需创建Set,除非您创建了自定义CodingKeys方法,并且无需创建自定义{{ 1}}方法,除非您执行一些自定义操作,例如使用init(from decoder:)并过滤重复的对象。对于init(from:)decodeIfPresent,您可以依赖综合的初始化程序。

您也不需要在循环中将数组中的元素添加到Playlists中,只需使用Tracks,它将接受List作为其输入参数。

append(objectsIn:)

如果要确保不会向Sequence两次添加任何对象,则需要使用class Songs: Object, Decodable { let playlists = List<Playlists>() let tracks = List<Tracks>() enum CodingKeys: String, CodingKey { case playlists, tracks } required convenience public init(from decoder: Decoder) throws { self.init() let container = try decoder.container(keyedBy: CodingKeys.self) if let playLists = try container.decodeIfPresent([Playlists].self, forKey: .playlists){ let uniquePlaylists = Set(playLists) self.playlists.append(objectsIn: uniquePlaylists) } if let tracksList = try container.decodeIfPresent([Tracks].self, forKey: .tracks){ let uniqueTrackList = Set(tracksList) self.tracks.append(objectsIn: uniqueTrackList) } } } class Playlists: Object, Codable, Hashable { @objc dynamic var id: String = "" @objc dynamic var name: String = "" @objc dynamic var duration: Int = 0 override static func primaryKey() -> String? { return "id" } } class Tracks: Object, Codable, Hashable { @objc dynamic var id: String = "" @objc dynamic var name: String = "" @objc dynamic var artist: Int = 0 override static func primaryKey() -> String? { return "id" } } 而不是Realm并使用add(_:,update:)来避免添加具有相同键的元素。

add