Realm 对象作为@Published 具有实时值

问题描述 投票:0回答:1

我有一个类

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
    }
}
ios swift realm combine
1个回答
0
投票

@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.

© www.soinside.com 2019 - 2024. All rights reserved.