Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 子类当前没有主键关系_Ios_Swift_Realm - Fatal编程技术网

Ios 子类当前没有主键关系

Ios 子类当前没有主键关系,ios,swift,realm,Ios,Swift,Realm,我有一个类似这样的JSON,它返回一个Posts的列表: [ { "id" : 1, "message": "Hello" "urls" : { "png" : "https://example.com/image.png", "jpg" : "

我有一个类似这样的JSON,它返回一个
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)

这个问题有两个问题

  • 如何在两个“表”之间创建关系
  • 防止重复
  • 让我谈谈(1)

    从一个类开始保存图像类型(.jpg等),然后保存url

    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