微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从ObserverableObject的ObserverableObject属性派生SwiftUI状态?

如何解决如何从ObserverableObject的ObserverableObject属性派生SwiftUI状态?

这是我的示例SwiftUI项目。我有一个ObservableObject类(资源),该类可获取数据并使用@Published来发布其获取的值。

class Resource: ObservableObject {
    @Published var value: User?

    func savetoDb(email: String) {
        dispatchQueue.global().async {
            //save to remote db
            let user = User.init(email: email)
            dispatchQueue.main.async {
                self.value = user
            }
        }
    }
}

我还有第二个ObservableObject类(Authenticator),它表示一个身份验证状态,该状态也使用@Published来发布其状态。身份验证器的状态是从其资源是否具有值得出的。

class Authenticator: ObservableObject {

    @Published var needsAuthentication = true
    //Can this be derived from resource.value != nil instead of subscribing to it
    //UI doesn't appear to update when this is changed unless I use the subscription
    @Published var resource = Resource()

    var subscription: AnyCancellable?

    public init() {
        subscription = resource.$value.map({ (user: User?) -> Bool in
            user == nil
        })
        .receive(on: RunLoop.main)
        .assign(to: \Authenticator.needsAuthentication,on: self)
    }
    deinit {
        subscription?.cancel()
    }

    func doSignInWithAppleStuff() {
        let email = "fromSignInWithAppleResult@email.com"
        resource.savetoDb(email: email)
    }
}

我目前正在使用Combine docs中描述的步骤来订阅资源的值,并更新身份验证器和随后的UI。

struct ContentView: View {
    @StateObject var authenticator = Authenticator()
    var body: some View {
        //How do I skip using the authenticators state and use the resource directly?
        if authenticator.needsAuthentication {
            Button("Sign In") {
                authenticator.doSignInWithAppleStuff()
            }
        } else {
            Text("Success")
                .padding()
        }
    }
}
struct User {
    let email: String
}

是否有替代的SwiftUI / Combine工具可以帮助Autenticator.needsAuthentication属性表示资源具有值,而无需手动创建订阅

我尝试禁用订阅并使用$authenticator.resource.value.wrappedValue == nil,但是UI不会更新。我猜是因为身份验证器没有发布其资源属性的更改。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。