如何避免在领域数据库中的自定义对象数组中重复,下面是我的代码和相关的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")
}
服务器发出相同响应时,如何避免重复数据。
答案 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