How to save a struct to realm in swift?

南楼画角 提交于 2019-11-28 08:37:15

To save a struct in Realm, means copying the data into a 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. This has practical benefits, such as the fact that a Realm Object's data is lazy loaded.

You can take advantage of Realm's approach by responding to the change notifications from a Realm instance. 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. Used properly this can simplify your code versus having multiple copies of values as structs.

I' suggest you to use protocols, to achive what you want.

1) Create your Struct

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

2) Create your Realm Object

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

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

4) Make your struct persistable

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

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!

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

Husam

Swift 4 shortest answer

Save structs as Data in Realm

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!