Запретить Realm переписывать свойство при обновлении объекта

Я установил REST API для объекта realm в iOS. Однако я нашел проблему с созданием любимого флага в моем объекте. Я создал любимый bool, однако каждый раз, когда объект обновляется из 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)
}

Ответы

Ответ 1

Есть два способа решить эту проблему:

1. Использовать Игнорированное свойство:

Вы можете сказать Realm, что определенное свойство не должно сохраняться. Чтобы ваше свойство favorite сохранялось в Realm, вы должны сделать это:

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. Сделайте частичное обновление

Или вы можете явно указать Realm, какие свойства следует обновить при обновлении объекта Pet:

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

Таким образом, свойство favorite не будет изменено.

Заключение

Существует одно большое различие между двумя подходами:

Игнорированное свойство:. Realm не сохранит свойство favorite вообще. Вы несете ответственность за их отслеживание.

Частичное обновление: Realm сохранит свойство "избранное", но оно не будет обновлено.

Я предполагаю, что частичные обновления - это то, что вам нужно для вашей цели.

Ответ 2

Если вы хотите быть более явным, есть третий вариант:

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

Ответ 3

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. Если вы делаете большие обновления пакета, возврат к каждому объекту не очень практичен и, безусловно, вызовет боль в дороге.

Я надеюсь, что это даст кому-то другой вариант, если он ему нужен.