首页 > 解决方案 > WWDC 2019“Combine in Practice”代码示例中的错误 CombineLatest?

问题描述

我尝试遵循 WWDC 2019 的“ Combine in Practice ”演讲的代码片段(从 26:00 分钟开始)或查看幻灯片179 ff。但它不会编译并且查看 API 某些部分对我来说没有意义(例如,CombineLatest.init(A, B)使用 type 的第三个参数调用closure。我试图调整示例以便它们编译。

问题第 1/2 部分:如果我误解了 WWDC 2019 代码片段,有人可以帮助我并告诉我吗?

第一个代码片段(幻灯片 179)

@Published var password: String = ""
@Published var passwordAgain: String = ""

var validatedPassword: CombineLatest<Published<String>, Published<String>, String?> {
    return CombineLatest($password, $passwordAgain) { password, passwordAgain in
        guard password == passwordAgain, password.count > 8 else { return nil }
        return password
    }
}

我只能让这个片段至少返回给我Publisher fromCombineLatest`

@Published var password: String = ""
@Published var passwordAgain: String = ""

var validatedPassword: Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher> {
    return Publishers.CombineLatest($password, $passwordAgain)
}

第二个代码片段(幻灯片 185)

@Published var password: String = ""
@Published var passwordAgain: String = ""

var validatedPassword: Map<CombineLatest<Published<String>, Published<String>, String?>> {
    return CombineLatest($password, $passwordAgain) { password, passwordAgain in
        guard password == passwordAgain, password.count > 8 else { return nil }
        return password
    }
    .map { $0 == "password1" ? nil : $0 }
}

我可以在以下情况下编译此代码段:

@Published var password: String = ""
@Published var passwordAgain: String = ""

var validatedPassword: Publishers.Map<Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher>, String?> {
        return Publishers.Map(upstream: Publishers.CombineLatest($password, $passwordAgain)) { password, passwordAgain in
            guard password == passwordAgain, password.count > 8 else { return nil }
            return password
    }

或者当包括.map {}幻灯片时:

@Published var password: String = ""
@Published var passwordAgain: String = ""
var validatedPassword: Publishers.Map<Publishers.Map<Publishers.CombineLatest<Published<String>.Publisher, Published<String>.Publisher>, String?>, String?> {
        return Publishers.Map(upstream: Publishers.CombineLatest($password, $passwordAgain)) { password, passwordAgain in
            guard password == passwordAgain, password.count > 8 else { return nil }
            return password
    }
    .map { $0 == "password1" ? nil : $0 }
}

问题第 2/2 部分:执行此操作的快捷方式是什么?例如,通过使用这样的东西(不编译):

@Published var password: String = ""
@Published var passwordAgain: String = ""

var validatedPassword: AnyPublisher<String?, Never> {
    return Just($password)
        .combineLatest($passwordAgain) { password, passwordAgain in
            guard password == passwordAgain, password.count > 8 else { return nil }
            return password
    }
    .map{ $0 == "password1" ? nil : $0 }
    .eraseToAnyPublisher()
}

标签: swiftgenericsswiftuicombinecombinelatest

解决方案


在第一季度:

WWDC 演示使用当时存在的 API。时间过去了 - API 已更改。而已。

在第二季度:

尝试如下...

var validatedPassword: AnyPublisher<String?, Never> {
    return Publishers.CombineLatest($password, $passwordAgain)
        .map { password, passwordRepeat in
            guard password == passwordRepeat, password.count > 8 else { return nil }
            return password
        }
        .map { ($0 ?? "") == "password1" ? nil : $0 }
        .eraseToAnyPublisher()
}

推荐阅读