我有一个类
Service
,它包含一个属性 user
,它是一个 Realm 对象。这个对象 - 它包含有关使用该应用程序的用户的信息 - 必须由不同的类(ViewModel
s)访问,这些类应该始终将所述对象的最新版本作为 @Published
属性。
(因为 Realm 对象正如他们所说的那样是“活的”,所以可以假设 @Published
属性在对象被修改时自动调用 objectWillChange
,但事实并非如此。)
class Service: NSObject {
static var shared: Service = Service()
@Published var user: User?
// realm is opened in RealmService, it is a synced realm ..
@MainActor
func loadOrGenerateOwnUser(userId: String) {
guard let realm = RealmService.shared.realm else {
print("realm not ready")
return
}
if let user = realm.objects(User.self).where( { $0._id == userId } ).first {
self.user = user
} else {
let user = User(_id: userId)
do {
try realm.write {
realm.add(user)
}
self.ownUser = user
} catch {
print("failed")
}
}
}
}
我是 iOS 开发的新手,但也许这可以使用 Combine 来完成?我看到领域对象具有
.publisher
属性,但是在执行 .sink
时没有收到任何值,只运行完成。
此代码应使用用户的最新值更新
@Published
类的 ObservableObject
...这根本不起作用:
class ViewModel: ObservableObject {
private var cancellables = Set<AnyCancellable>()
@Published var ownUser: User?
init() {
setupBindings()
}
func setupBindings() {
Service.shared.user.publisher
.receive(on: DispatchQueue.main)
.sink { completion in print("Completed with \(completion)") // this is called once only
} receiveValue: { [weak self] ownUser in
print("----------------test") // this is never called
self?.user = user
}
.store(in: &cancellables)
}
}
P.S:有没有更好的方法让整个应用程序都可以访问用户数据?我不确定这是否是一个好方法,因为我找不到关于此类问题的太多信息..
P.P.S: 用户对象
class User: Object, ObjectKeyIdentifiable, Decodable {
@Persisted(primaryKey: true) var _id: String
@Persisted var userName: String?
// more
convenience init(_id: String, userName: String? = nil) {
self.init()
self._id = _id
self.userName = userName
}
}
@Published
只能在“值”改变时触发objectWillChange
。
class User
是引用类型,当您更改属性时不会更改其值。
此外,Realm 属性隐藏在几层
ObservableObject
s 包装器和方法的后面,这些包装器和方法隐藏在 @Persisted
中
你应该使用
@ObservedResults(User.self) var users
https://www.mongodb.com/docs/realm/sdk/swift/swiftui/pass-realm-data-between-views/
@ObservedRealmObject var user: User
https://www.mongodb.com/docs/realm/sdk/swift/swiftui/react-to-changes/
Swift SDK 提供了 @ObservedResults 属性包装器,可让您观察查询结果的集合。您可以快速写入 ObservedResults 集合,当观察到的查询发生变化时,视图会自动更新。
You can create your own
property wrapper
that conforms to DynamicProperty
to mimic something like ViewModel
but it isn't ideal.