Ios 子类当前没有主键关系
我有一个类似这样的JSON,它返回一个Ios 子类当前没有主键关系,ios,swift,realm,Ios,Swift,Realm,我有一个类似这样的JSON,它返回一个Posts的列表: [ { "id" : 1, "message": "Hello" "urls" : { "png" : "https://example.com/image.png", "jpg" : "
Post
s的列表:
[
{
"id" : 1,
"message": "Hello"
"urls" : {
"png" : "https://example.com/image.png",
"jpg" : "https://example.com/image.jpg",
"gif" : "https://example.com/image.gif"
}
}
]
如你所见,我需要上两门课。一个用于父对象(Post
),一个用于对象“url”
(PostUrls
)
我是这样做的:
class Post: Object, Decodable {
@objc dynamic var id = 0
@objc dynamic var message: String? = nil
@objc dynamic var urls: PostUrls? = nil
override static func primaryKey() -> String? {
return "id"
}
private enum PostCodingKeys: String, CodingKey {
case id
case message
case urls
}
convenience init(id: Int, message: String, urls: PostUrls) {
self.init()
self.id = id
self.message = message
self.urls = urls
}
convenience required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: PostCodingKeys.self)
let id = try container.decode(Int.self, forKey: .id)
let message = try container.decode(String.self, forKey: .message)
let urls = try container.decode(PostUrls.self, forKey: .urls)
self.init(id: id, message: message, urls: urls)
}
required init() {
super.init()
}
}
及
但是,问题是我在Post
和PostUrls
之间没有关系,因为没有连接这两者的主键。此外,这也意味着我目前无法控制PostUrls
表中的重复项
因此,我的问题是:如何在两个表之间创建关系,并防止在
PostUrls
表中重复?在这种情况下,这些对象之间确实存在关系。对象Post
包含对象PostUrls
。Realm不需要主键来拥有这种关系,因为它在幕后创建主键。所以它使用它,即使你不能访问它
要手动设置primaryKey,必须重写名为primaryKey()的func
通过这种方式,您可以告诉realm您希望将此属性用作唯一键。
为了防止重复,有两种方法。首先-尝试查找数据库中已存在id为id
的对象,如果该对象存在,请不要创建它
第二,将冲突处理程序添加到域的保存方法。可以设置仅修改具有相同ID的对象,而不复制。或者,您可以说,当您尝试插入重复对象时,您希望抛出一个错误
realm.add(objects, update: update ? .modified : .error)
这个问题有两个问题
class ImageUrlClass: Object {
@objc dynamic var imageType = ""
@objc dynamic var imageUrl = ""
}
然后是处理解码的主类
class Post: Object, Decodable {
@objc dynamic var id: Int = 0
@objc dynamic var message: String = ""
let urlList = List<ImageUrlClass>()
...edited for brevity
convenience init(id: Int, message: String, urls: [String: String]) {
self.init()
self.id = id
self.message = message
//create a ImageUrlClass from each dictionary entry
for url in urls {
let key = url.key
let value = url.value
let aUrl = ImageUrlClass(value: ["imageType": key, "imageUrl": value])
self.urlList.append(aUrl)
}
}
convenience required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: PostCodingKeys.self)
let id = try container.decode(Int.self, forKey: .id)
let message = try container.decode(String.self, forKey: .message)
let urls = try container.decode([String: String].self, forKey: .urls)
self.init(id: id, message: message, urls: urls)
}
}
这将导致这样的输出
1
Hello
jpg https://example.com/image.jpg
png https://example.com/image.png
gif https://example.com/image.gif
我给出了一个答案来回答你关于人际关系问题的第一部分。然而,防止重复是一个完全不同的问题。您如何确定某个对象是否为重复类型。jpg、.gif等或重复url或两者都有。。。或者别的什么?这个答案对这个问题来说并不正确,但你的物体之间有概念上的关系是正确的。利用列表是一种解决方案。我不认为主键对答案有影响;虽然它会阻止两个对象拥有相同的主键(它们是唯一的),但它不会阻止对象内的重复数据,这就是OP所要问的(我认为)。因此,您可以使用主键id为1的对象和指向www.somejpg.com的jpg,然后使用主键id为2的对象指向完全相同的对象。@Jay没有人阻止将URL用作主键,因此您将拥有唯一的URL。或者在添加它们之前手动检查。或者您可以在领域中使用复合键,就像在常规数据库中一样。url是一个具有挑战性的主键,就好像它发生了变化一样,它使该对象和其他数据无效。也许答案可以扩展和澄清,以解决以下问题:a)在Post对象及其类型和URL之间创建关系;b)防止重复数据?你能提供一些这样做的代码吗?它当前使用的是一个不会创建关系或防止重复的整数主键。
class Post: Object, Decodable {
@objc dynamic var id: Int = 0
@objc dynamic var message: String = ""
let urlList = List<ImageUrlClass>()
...edited for brevity
convenience init(id: Int, message: String, urls: [String: String]) {
self.init()
self.id = id
self.message = message
//create a ImageUrlClass from each dictionary entry
for url in urls {
let key = url.key
let value = url.value
let aUrl = ImageUrlClass(value: ["imageType": key, "imageUrl": value])
self.urlList.append(aUrl)
}
}
convenience required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: PostCodingKeys.self)
let id = try container.decode(Int.self, forKey: .id)
let message = try container.decode(String.self, forKey: .message)
let urls = try container.decode([String: String].self, forKey: .urls)
self.init(id: id, message: message, urls: urls)
}
}
let decoder = JSONDecoder()
let post = try! decoder.decode(Post.self, from: encodedData)
print(post.id)
print(post.message)
for url in post.urlList {
let a = url.imageType
let b = url.imageUrl
print(a,b)
}
1
Hello
jpg https://example.com/image.jpg
png https://example.com/image.png
gif https://example.com/image.gif