Object
から継承することで、クラスでRealmを簡単に使用できます。しかし、Swiftのレルムにいくつかのフィールドを含むstruct
を保存するにはどうすればよいですか?例えば。
struct DataModel {
var id = 0
var test = "test"
}
サポートされているタイプについてのドキュメントが明確であることを私は知っています。しかし、おそらく素晴らしい回避策があるか、あるいはもっと良いことに、レルムの誰かが構造体に関する将来の計画について書くことができます。
レルムにstruct
を保存するということは、データをレルムObject
にコピーすることを意味します。レルムObjects
がクラスでありstructs
ではない理由は、それらが不活性値ではなく、レルムの永続データを表すオブジェクトを自動更新するためです。これには、レルムObject
のデータが遅延ロードされるという事実などの実用的な利点があります。
レルムインスタンスからの変更通知に応答することで、レルムのアプローチを利用できます。たとえば、UITableView
データソースがレルムObject
の配列プロパティに基づいている場合、そのオブジェクトのインスタンスがある限り、通知後にそれが正しいことを表すことが保証されます値。これを適切に使用すると、構造体として値の複数のコピーを持つのではなく、コードを簡素化できます。
プロトコルを使用して、必要なものを実現することをお勧めします。
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)
}
構造体をデータとしてレルムに保存
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)
}
Ludovicを示唆することを行うか、 nrealm を使用して、そのプロセスを自動化し、各構造体の定型コードを削除することができます。