如何将 Realm 与 SwiftUI 表单一起使用
How to use Realm with SwiftUI forms
Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
对托管对象的所有更改(添加、修改和删除)都必须在写入事务中完成。例如,
// Update an object with a transaction
try! realm.write {
author.name = "Thomas Pynchon"
}
我可以使一个Realm子class符合ObservableObject。但是,我看不到如何在 SwiftUI 中使领域属性可更新。下面的领域 属性 示例。
@objc dynamic var myName: String = "Adam"
Realm 基于@objc 动态变量自动设置模式。我看不到在领域 属性 上获取 @Published 的方法。 SwiftUI 将呈现一个 TextField,但在编辑该值时崩溃。
TextField("Quantity (\(shoppingItem.myUnit!.myName))", value: $shoppingItem.stdQty, formatter: basicFormat)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numbersAndPunctuation)
有什么方法可以将 SwiftUI 状态更改包装在 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。
另一种方法是使用自定义绑定,当设置 属性 时,打开一个事务并将数据保存到领域。
TextField("Quantity (\(shoppingItem.myUnit!.myName))",
value: Binding(get: {shoppingItem.stdQty},
set: {(value) in
//if your state property is in a view model, all this code could be like viewModel.saveData(newMessage: value)
let realm = try! Realm()
try! realm.write {
shoppingItem.stdQty = value
}
}),
formatter: basicFormat)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numbersAndPunctuation)
这将在每个插入的角色上保存到领域
Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
对托管对象的所有更改(添加、修改和删除)都必须在写入事务中完成。例如,
// Update an object with a transaction
try! realm.write {
author.name = "Thomas Pynchon"
}
我可以使一个Realm子class符合ObservableObject。但是,我看不到如何在 SwiftUI 中使领域属性可更新。下面的领域 属性 示例。
@objc dynamic var myName: String = "Adam"
Realm 基于@objc 动态变量自动设置模式。我看不到在领域 属性 上获取 @Published 的方法。 SwiftUI 将呈现一个 TextField,但在编辑该值时崩溃。
TextField("Quantity (\(shoppingItem.myUnit!.myName))", value: $shoppingItem.stdQty, formatter: basicFormat)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numbersAndPunctuation)
有什么方法可以将 SwiftUI 状态更改包装在 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。
另一种方法是使用自定义绑定,当设置 属性 时,打开一个事务并将数据保存到领域。
TextField("Quantity (\(shoppingItem.myUnit!.myName))",
value: Binding(get: {shoppingItem.stdQty},
set: {(value) in
//if your state property is in a view model, all this code could be like viewModel.saveData(newMessage: value)
let realm = try! Realm()
try! realm.write {
shoppingItem.stdQty = value
}
}),
formatter: basicFormat)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numbersAndPunctuation)
这将在每个插入的角色上保存到领域