简体   繁体   English

如何在swift中将结构保存到领域?

[英]How to save a struct to realm in swift?

It is easy to use Realm with classes by inheriting from Object . 通过继承Object可以很容易地将Realm与类一起使用。 But how would I save a struct containing several fields to realm in Swift? 但是如何在Swift中将包含多个字段的struct保存到领域? Eg 例如

struct DataModel {
    var id = 0
    var test = "test"
}

I know the documentation is clear about supported types. 我知道文档很清楚支持的类型。 But maybe there is nice workaround or - even better - someone from realm could write about future plans about structs. 但也许有一个很好的解决方法或 - 甚至更好 - 来自领域的人可以写关于结构的未来计划。

I' suggest you to use protocols, to achive what you want. 我建议你使用协议,以达到你想要的。

1) Create your Struct 1)创建你的结构

struct Character {
    public let identifier: Int
    public let name: String
    public let realName: String
}

2) Create your Realm Object 2)创建您的Realm对象

final class CharacterObject: Object {
    dynamic var identifier = 0
    dynamic var name = ""
    dynamic var realName = ""
    override static func primaryKey() -> String? {
        return "identifier"
    }
}

3) Use protocols to transform our struct to Realm Object 3)使用协议将我们的结构转换为Realm对象

public protocol Persistable {
    associatedtype ManagedObject: RealmSwift.Object
    init(managedObject: ManagedObject)
    func managedObject() -> ManagedObject
}

4) Make your struct persistable 4)使您的结构可持久化

extension Character: Persistable {
    public init(managedObject: CharacterObject) {
        identifier = managedObject.identifier
        name = managedObject.name
        realName = managedObject.realName
    }
    public func managedObject() -> CharacterObject {
        let character = CharacterObject()
        character.identifier = identifier
        character.name = name
        character.realName = realName
        return character
    }
}

With these tools in place, we are ready to implement the insertion methods of our persistence layer. 有了这些工具,我们就可以实现持久层的插入方法了。

5) Exemple to write datas 5)编写数据的例子

public final class WriteTransaction {
    private let realm: Realm
    internal init(realm: Realm) {
        self.realm = realm
    }
    public func add<T: Persistable>(_ value: T, update: Bool) {
        realm.add(value.managedObject(), update: update)
    }
}

// Implement the Container
public final class Container { 
    private let realm: Realm
    public convenience init() throws {
        try self.init(realm: Realm())
    }
    internal init(realm: Realm) {
        self.realm = realm
    }
    public func write(_ block: (WriteTransaction) throws -> Void) 
    throws {
        let transaction = WriteTransaction(realm: realm)
        try realm.write {
            try block(transaction)
        }
    }
}

5) Use the magic! 5)使用魔法!

let character = Character(
    identifier: 1000,
    name: "Spiderman",
    realName: "Peter Parker"
)
let container = try! Container()
try! container.write { transaction in
    transaction.add(character)
}

Amazing source : Using Realm with Value Types & My Article 惊人的来源: 使用具有价值类型的领域我的文章

To save a struct in Realm, means copying the data into a Realm Object . 要在Realm中保存struct ,意味着将数据复制到Realm Object The reason why Realm Objects are classes and not structs is because they are not inert values, but auto-updating objects that represent the persisted data in Realm. Realm Objects是类而不是structs的原因是因为它们不是惰性值,而是自动更新表示Realm中持久数据的对象。 This has practical benefits, such as the fact that a Realm Object 's data is lazy loaded. 这具有实际的好处,例如Realm Object的数据是延迟加载的。

You can take advantage of Realm's approach by responding to the change notifications from a Realm instance. 您可以通过响应来自Realm实例的更改通知来利用Realm的方法。 For example if your UITableView data source is based off an array property on a Realm Object , as long as you have an instance of that object, you are guaranteed that after the notification it represents the correct values. 例如,如果您的UITableView数据源基于Realm Object上的数组属性,只要您拥有该对象的实例,就可以保证在通知后它表示正确的值。 Used properly this can simplify your code versus having multiple copies of values as structs. 如果使用得当,这可以简化代码,而不是将多个值副本作为结构。

Swift 4 shortest answer 斯威夫特4最短的回答

Save structs as Data in Realm 将结构保存为Realm中的Data

struct MyStruct : Codable { // Variables here }

class MyRealObject : Object {

    @objc private dynamic var structData:Data? = nil

    var myStruct : MyStruct? {
        get {
            if let data = structData {
                return try? JSONDecoder().decode(MyStruct.self, from: data)
            }
            return nil
        }
        set {
            structData = try? JSONEncoder().encode(newValue)
        }
    }
}

Use the magic 使用魔法

let realm = try! Realm()
try! realm.write {
      let myReal = MyRealObject()
      myReal.myStruct = MyStruct(....)
      realm.add(myReal)
}

You can do what suggests Ludovic, or you can automate that process and get rid of that boilerplate code for each of your structs by using Unrealm . 你可以做Ludovic的建议,或者你可以通过使用Unrealm来自动化这个过程并摆脱每个结构的样板代码。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM