web-dev-qa-db-ja.com

構造体をレルムにすばやく保存する方法は?

Objectから継承することで、クラスでRealmを簡単に使用できます。しかし、Swiftのレルムにいくつかのフィールドを含むstructを保存するにはどうすればよいですか?例えば。

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

サポートされているタイプについてのドキュメントが明確であることを私は知っています。しかし、おそらく素晴らしい回避策があるか、あるいはもっと良いことに、レルムの誰かが構造体に関する将来の計画について書くことができます。

10
beseder

レルムにstructを保存するということは、データをレルムObjectにコピーすることを意味します。レルムObjectsがクラスでありstructsではない理由は、それらが不活性値ではなく、レルムの永続データを表すオブジェクトを自動更新するためです。これには、レルムObjectのデータが遅延ロードされるという事実などの実用的な利点があります。

レルムインスタンスからの変更通知に応答することで、レルムのアプローチを利用できます。たとえば、UITableViewデータソースがレルムObjectの配列プロパティに基づいている場合、そのオブジェクトのインスタンスがある限り、通知後にそれが正しいことを表すことが保証されます値。これを適切に使用すると、構造体として値の複数のコピーを持つのではなく、コードを簡素化できます。

14
Adam Fish

プロトコルを使用して、必要なものを実現することをお勧めします。

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)プロトコルを使用して構造体をレルムオブジェクトに変換します

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

すばらしい情報源: 値型でレルムを使用私の記事

34
Ludovic

Swift4の最短回答

構造体をデータとしてレルムに保存

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

魔法を使う

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

Ludovicを示唆することを行うか、 nrealm を使用して、そのプロセスを自動化し、各構造体の定型コードを削除することができます。

enter image description here

1
arturdev