web-dev-qa-db-ja.com

オブジェクトの更新時にレルムがプロパティを上書きしないようにする

IOSのレルムオブジェクトにREST APIを設定しました。しかし、オブジェクトにお気に入りのフラグを作成する際に問題が見つかりました。お気に入りのブール値を作成しましたが、オブジェクトは毎回はAPIから更新され、お気に入りをデフォルトのfalseに再度設定します。お気に入りはローカルにのみ保存されるため、このフラグは更新されないようにします。これを実現するにはどうすればよいですか?

class Pet: Object{
    dynamic var id: Int = 1
    dynamic var title: String = ""
    dynamic var type: String = ""
    dynamic var favorite: Bool = false


    override class func primaryKey() -> String {
        return "id"
    }
}

CreateOrUpdate

let pet = Pet()
pet.id = 2
pet.name = "Dog"
pet.type = "German Shephard"


try! realm.write {
    realm.add(pet, update: true)
}
22
Peter Pik

これを解決するには2つの方法があります。

1。無視されたプロパティを使用します:

特定のプロパティを永続化してはならないことをレルムに伝えることができます。 favoriteプロパティがレルムによって永続化されるのを防ぐには、次のようにする必要があります。

class Pet: Object{
    dynamic var id: Int = 1
    dynamic var title: String = ""
    dynamic var type: String = ""
    dynamic var favorite: Bool = false

    override class func primaryKey() -> String {
        return "id"
    }

    override static func ignoredProperties() -> [String] {
       return ["favorite"]
   }
}

またはあなたができる

2。部分更新を行う

または、Petオブジェクトを更新するときに、どのプロパティを更新する必要があるかをRealmに明示的に指示することもできます。

try! realm.write {
  realm.create(Pet.self, value: ["id": 2, "name": "Dog", "type": "German Shepard"], update: true)
}

このようにして、favoriteプロパティは変更されません。

結論

2つのアプローチには大きな違いが1つあります。

無視されたプロパティ:レルムはfavoriteプロパティをまったく保存しません。それらを追跡するのはあなたの責任です。

部分的な更新:レルムは「お気に入り」プロパティを保存しますが、更新されません。

部分的な更新はあなたがあなたの目的のために必要なものだと思います。

22
joern

より明確にしたい場合は、3番目のオプションがあります。

。更新の現在の値を取得します

// Using the add/update method
let pet = Pet()
pet.id = 2
pet.name = "Dog"
pet.type = "German Shephard"

if let currentObject = realm.object(ofType: Pet.self, forPrimaryKey: 2) {
    pet.favorite = currentObject.favorite
}

try! realm.write {
    realm.add(pet, update: true)
}

// Using the create/update method
var favorite = false
if let currentObject = realm.object(ofType: Pet.self, forPrimaryKey: 2) {
    favorite = currentObject.favorite
}

// Other properties on the pet, such as a list will remain unchanged
try! realm.write {
    realm.create(Pet.self, value: ["id": 2, "name": "Dog", "type": "German Shephard", "favorite": favorite], update: true)
}
19
Adam Fish

4。NSUserDefaults(または実際には他のデータストア)

同じ問題が発生し、別のデータストア(NSUserDefaults)に保存するという従来のオプションを選択しました。私の場合、ユーザーが最後にアイテムを表示したときに保存し、このデータをNSUserDefaultsに保存するのが適切だと感じました。私は次のようなことをしました:

まず、保存しているオブジェクトの一意のキーを定義します(selfは、表示およびレンダリングされるモデルオブジェクトです)。

- (NSString *)lastViewedDateKey {
    // Note each item gets a unique key with <className>_<itemId> guaranteeing us uniqueness
    return [NSString stringWithFormat:@"%@_%ld", self.class.className, (long)self.itemId];
}

次に、ユーザーがアイテムを表示したら、キーを次のように設定します。

- (void)setLastViewedToNow {
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:[NSDate date] forKey:self.lastViewedDateKey];
    [userDefaults synchronize];
}

後で、私はそれを次のように使用します:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDate *createdOnDate = <passed in from elsewhere>;
NSDate *lastViewedDate = [userDefaults objectForKey:self.lastViewedDateKey];
if (!lastViewedDate || [createdOnDate compare:lastViewedDate] == NSOrderedDescending) {
    ...
}

上記のソリューションとは対照的に:1。データの永続性はありません。 2.これにより、オブジェクトのプロパティを定義する必要があるさらに別の場所が作成され、新しいプロパティが追加されるたびにこのリストを更新するのを忘れると、エラーが発生する可能性があります。 3.大規模なバッチ更新を行う場合、すべてのオブジェクトをさかのぼることは実際には実用的ではなく、将来的には確かに苦痛を引き起こします。

彼らがそれを必要とするならば、これが誰かに別のオプションを与えることを願っています。

0
salil