合并发布者:当任何发布者更改值时通知

Combine publishers: notify when ANY of the publishers changes a value

我想在 usernamepassword 已发布属性的每次更改时触发“更改”事件,并设置一个新的 Credentials 已发布 属性从这两个派生并发出一个事件。

使用 SwiftUI 和 Combine 实现此结果的最简单解决方案是什么?

我试图实现的一些示例代码:

import SwiftUI
import Combine
import Foundation

struct Credentials {
    let username: String
    let password: String

    init(username: String = "",
         password: String = "") {
        self.userName = username
        self.password = password
    }
}

final class ViewModel: ObservableObject {
    @Published var username = ""
    @Published var password = ""

    @Published var credentials = Credentials()


    init() {
        [$username, $password]// ..... What to do here? 
// How to "subscribe" each of those properties to emit an event
// so that I get notified each time one of them changes

        credentials = Credentials(username: $username, password: $password)
    }
}

基本上,我正在寻找与此答案类似的内容:

但是通知应该在每次任何发布者产生一个值时被触发,而不是所有的发布者。

您不想像在您的链接问题中那样使用 Publishers.MergeMany,而是想在您的第一个发布商上使用 .combineLatest(_:),如下所示:

import SwiftUI
import Combine
import Foundation

struct Credentials {
    let username: String
    let password: String

    init(username: String = "",
         password: String = "") {
        self.userName = username
        self.password = password
    }
}

final class ViewModel: ObservableObject {
    @Published var username = ""
    @Published var password = ""

    @Published var credentials = Credentials()

    private var cancellable: Cancellable? = nil


    init() {
        cancellable = $username.combineLatest($password).sink { tuple in
            self.credentials = Credentials(username: tuple.0, password: tuple.1)
        }

        credentials = Credentials(username: username, password: password)
    }
}

(有点过了,所以这段代码可能不会立即 运行,但希望你能看到这是怎么回事)。