一尘不染

如何快速保存结构?

swift

通过从继承可以很容易地将Realm与类一起使用Object。但是我如何将struct包含几个字段的a保存到Swift中呢?例如

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

我知道文档中明确支持的类型。但是也许有一个不错的解决方法,或者甚至更好-来自领域的人可以写有关结构的未来计划。


阅读 224

收藏
2020-07-07

共1个答案

一尘不染

我建议您使用协议,以实现所需的功能。

1)创建您的结构

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

2)创建您的领域对象

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

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

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

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
    }
}

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

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)使用魔术!

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

惊人的来源:将领域与值类型我的文章一起使用

2020-07-07