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

bes*_*der 10 realm swift

通过继承,可以很容易地将Realm与类一起使用Object.但是如何struct在Swift中保存包含几个字段的域?例如

struct DataModel {
    var id = 0
    var test = "test"
}
Run Code Online (Sandbox Code Playgroud)

我知道文档很清楚支持的类型.但也许有一个很好的解决方法或 - 甚至更好 - 来自领域的人可以写关于结构的未来计划.

Lud*_*vic 33

我建议你使用协议,以达到你想要的.

1)创建你的结构

struct Character {
    public let identifier: Int
    public let name: String
    public let realName: String
}
Run Code Online (Sandbox Code Playgroud)

2)创建您的Realm对象

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

3)使用协议将我们的结构转换为Realm对象

public protocol Persistable {
    associatedtype ManagedObject: RealmSwift.Object
    init(managedObject: ManagedObject)
    func managedObject() -> ManagedObject
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

有了这些工具,我们就可以实现持久层的插入方法了.

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

5)使用魔法!

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

惊人的来源:使用具有价值类型的领域我的文章

  • 您分享的文章中的一些更新:transaction.add(character, update: true) (2认同)

Ada*_*ish 14

struct在Realm中保存,意味着将数据复制到Realm中Object.Realm Objects是类的原因structs是因为它们不是惰性值,而是自动更新表示Realm中持久数据的对象.这具有实际的好处,例如Realm Object的数据是延迟加载的.

您可以通过响应来自Realm实例的更改通知来利用Realm的方法.例如,如果您的UITableView数据源基于Realm上的数组属性Object,只要您拥有该对象的实例,就可以保证在通知后它表示正确的值.如果使用得当,这可以简化代码,而不是将多个值副本作为结构.


Hus*_*sam 7

斯威夫特4最短的回答

将结构保存为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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用魔法

let realm = try! Realm()
try! realm.write {
      let myReal = MyRealObject()
      myReal.myStruct = MyStruct(....)
      realm.add(myReal)
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是简单地将JSON blob存储到数据库中吗?这抑制了利用谓词搜索和过滤该数据的效率. (4认同)

art*_*dev 5

您可以按照 Ludovic 的建议进行操作,也可以使用Unrealm自动化该过程并删除每个结构的样板代码。

在此输入图像描述