Swift Realm: как обрабатывать ошибку при добавлении нового объекта с тем же первичным ключом?

#swift #realm

#swift #область

Вопрос:

Я использую RealmSwift в своем проекте. (Я новичок в realm) когда я хочу добавить новый объект с тем же первичным ключом, мое приложение завершило работу с этой ошибкой:

Попытка создать объект типа ‘Card’ с существующим значением первичного ключа.

как я могу обработать эту ошибку без сбоев. это мои коды модели:

 class Card: Object, Decodable {

    @objc dynamic var pan           = ""
    @objc dynamic var title         = ""

    override class func primaryKey() -> String? {
        return CodingKeys.pan.stringValue
    }

    private enum CodingKeys: CodingKey {
        case pan
        case title
    }

    required convenience init(from decoder: Decoder) throws {
        self.init()
        let values = try decoder.container(keyedBy: CodingKeys.self)
    
        self.pan        = try values.decode(String.self, forKey: .pan)
        self.title      = ""
    }
}
  

и это мои коды менеджера базы данных:

 class DatabaseRequest {

    func addCard(_ card: Card) -> Bool {
    
        let realm = try! Realm()
        do {
            try realm.write {
                realm.add(card)
            }
            return true
        } catch let error as NSError {
            print(error)
            return false
        }
    }
}
  

я видел какое-то решение, например, проверить, существует ли объект с тем же первичным ключом, прежде чем добавлять его в базу данных.

почему эта часть кода никогда не выполнялась и для чего это?

     } catch let error as NSError {
        print(error)
        return false
    }
  

Комментарии:

1. Первичные ключи уникальны, что означает, что вы не можете и не должны пытаться добавить другой объект, который имеет тот же первичный ключ. Решения нет, поскольку вы не можете этого сделать. Можете ли вы объяснить, почему вам нужны два объекта с одинаковым первичным ключом? Кроме того, это не первичный ключ, return CodingKeys.pan.stringValue где бы это ни было return pan . Смотрите руководство по области Первичные ключи . Вероятно, мы можем помочь с моделированием, но нужна дополнительная информация — обновите вопрос, пожалуйста.

2. Кроме того, обычной практикой является разрешить realm / swift автоматически назначать первичные ключи объектам — тогда вам не придется беспокоиться об их обработке, поскольку они всегда будут уникальными. Распространенным шаблоном является присвоение значению первичного ключа значения NSUUID(). UUIDString для генерации уникальных идентификаторов строк. Таким образом, это будет выглядеть как @objc dynamic var my_primary_key = NSUUID().UUIDString

Ответ №1:

По умолчанию update свойством является .error , что означает, что вы получите сообщение об ошибке при попытке создать или добавить объект с тем же первичным ключом.

Чтобы предотвратить это, просто установите для update свойства значение .modifed или .all

realm.add(card, update: .all)

Комментарии:

1. realm.add(card, update: .all) обновит все свойства, даже если оно равно нулю. Для вас это будет выглядеть так, как будто вы создаете новый объект с тем же первичным ключом.

2. это хорошо, но почему часть catch никогда не выполнялась?

3. OP не пытается обновить объект, поэтому этот ответ не будет применяться (хотя он предназначен для обновления существующего объекта!)