Как использовать Realm с формами SwiftUI - PullRequest
0 голосов
/ 22 марта 2020

Завершение приложения из-за необработанного исключения «RLMException», причина: «Попытка изменить объект вне транзакции записи - сначала вызовите beginWriteTransaction для экземпляра RLMRealm.»

Все изменения в управляемый объект (добавление, изменение и удаление) должен быть выполнен в транзакции записи. Например,

// Update an object with a transaction
try! realm.write {
    author.name = "Thomas Pynchon"
}

I может сделать подкласс Realm соответствующим ObservableObject. Однако я не вижу, как сделать свойства области обновляемыми в SwiftUI. Пример свойства объекта ниже.

@objc dynamic var myName: String = "Adam"

Область автоматически устанавливает схему на основе @ obj c dynamici c var. Я не вижу способа получить @Published для свойства области. SwiftUI отобразит TextField, но вылетает при редактировании значения.

TextField("Quantity (\(shoppingItem.myUnit!.myName))", value: $shoppingItem.stdQty, formatter: basicFormat)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.numbersAndPunctuation)

Есть ли способ обернуть изменения состояния SwiftUI внутри транзакции записи Realm?

1 Ответ

0 голосов
/ 24 марта 2020

Рассмотрим свойство Realm, stdQty, показанное ниже. Его можно изменить только внутри транзакции записи.

import RealmSwift
import Combine

class ShoppingItems: Object, ObservableObject    
    let objectWillChange = PassthroughSubject<Void, Never>()
    @objc dynamic var stdQty: Double = 1

Невозможно связать stdQty без ошибки в исходном вопросе. Однако вы можете создать вычисляемую переменную, которую можно связать.

    var formQty: Double {
        get {
            return stdQty
        } 
        set {
            objectWillChange.send()
            if let sr = self.realm {
                try! sr.write {
                    stdQty = newValue
                }
            }
        }
    }

Связывание вычисленной переменной работает нормально.

TextField("Quantity (\(shoppingItem.myUnit!.myName))", value: $shoppingItem.formQty, formatter: basicFormat)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.numbersAndPunctuation)

Ограничение ответа: objectWillChange запускается только вычисляемой переменной. Изменения в форме отражаются в форме. Изменения в области еще не вызывают Combine objectWillChange.

...