1

我尝试遵循 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`

  • Publishers枚举添加到CombineLatest
  • 删除尾随闭包
  • 添加.PublisherPublished<String>
@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 }
}

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

  • 执行第一个片段列出的所有步骤
  • Publishers.在前面添加Map
  • 移动<>到正确的位置
  • 显式返回Publishers.Map并使用正确的参数upstream:
@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 {}幻灯片时:

  • 通过将 var 类型包装在另一个Publishers.Map<..., String?>
@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()
}
4

1 回答 1

0

在第一季度:

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()
}
于 2019-11-16T11:11:38.090 回答