如何使用 Combine 实现我的 MVP / Rxswift
How to implement my MVP / Rxswift with Combine
通常我会这样组织我的代码(以简化的方式):
演示者订阅我的模型(通过经理)
myManager.getItems(...).subscribe { .... }.disposed()
Manager 从 Provider 调用 getItems 并转换 DTO -> BO :
func getItems(...) -> Single<myObectBO> {
myProvider.getItems(...).map { myDTO in
return MyObjectBO(withDTO: myDTO)
}
}
提供商return一个DTO:
func getItems(...) -> Single<myObectDTO> {
...
return Single.just(myObectDTO)
}
我尝试了不同的方法,但目前我没有发现在 Combine 中可以实现它,有没有简单的方法可以做到这一点?
感谢您的帮助。
更明确地说,我想做类似的事情:
func getSomething() {
getManagerFuture()
.sink { result in
print(result)
}
}
func getManagerFuture() -> Future<[MyBO], ManagerError> {
Future { promise in
getProviderFuture()
.flatMap { dtoList -> ([MyBO], ManagerError) in
let boList = dtoList.map { dto in
return MyBO(id: dto.id, name: dto.name)
}
return promise(.success(boList))
}
}
}
func getProviderFuture() -> Future<[MyDTO], ProviderError> {
// should be a webservice call
let dto1 = MyDTO(id: 1, name: "one")
let dto2 = MyDTO(id: 2, name: "two")
return Future { promise in promise(.success([dto1, dto2])) }
}
我在 getManagerProvider 上有这个错误:
Instance method 'flatMap(maxPublishers:_:)' requires the types
'([MyBO], ManagerError).Failure' and 'Never' be equivalent
Type '([MyBO], ManagerError)' cannot conform to 'Publisher'; only
struct/enum/class types can conform to protocols
我有这样的东西,它在操场上运行良好。
为了精确起见,最好删除发布者,以便能够在不更改代码外部的情况下更改您的实现
enum DTOError: Error {
case wrongDTO
}
enum BOError: Error {
case wrongBO
}
struct DTO {
let value = "Value"
}
struct BO {
let value: String
init(dto: DTO) {
self.value = dto.value
}
}
func getDTO() -> AnyPublisher<DTO, DTOError> {
Future { promise in
promise(.success(DTO()))
}
.eraseToAnyPublisher()
}
func getBO() -> AnyPublisher<BO, BOError> {
getDTO()
.flatMap({ dto -> Future<BO, DTOError> in
Future<BO, DTOError> { promise in
promise(.success(BO(dto: dto)))
}
})
.mapError { dtoError -> BOError in
.wrongBO
}
.eraseToAnyPublisher()
}
getBO()
.sink(receiveCompletion: { completion in
print(completion)
}) { data in
print(data)
}
虽然可能有更简洁的解决方案
通常我会这样组织我的代码(以简化的方式):
演示者订阅我的模型(通过经理)
myManager.getItems(...).subscribe { .... }.disposed()
Manager 从 Provider 调用 getItems 并转换 DTO -> BO :
func getItems(...) -> Single<myObectBO> {
myProvider.getItems(...).map { myDTO in
return MyObjectBO(withDTO: myDTO)
}
}
提供商return一个DTO:
func getItems(...) -> Single<myObectDTO> {
...
return Single.just(myObectDTO)
}
我尝试了不同的方法,但目前我没有发现在 Combine 中可以实现它,有没有简单的方法可以做到这一点? 感谢您的帮助。
更明确地说,我想做类似的事情:
func getSomething() {
getManagerFuture()
.sink { result in
print(result)
}
}
func getManagerFuture() -> Future<[MyBO], ManagerError> {
Future { promise in
getProviderFuture()
.flatMap { dtoList -> ([MyBO], ManagerError) in
let boList = dtoList.map { dto in
return MyBO(id: dto.id, name: dto.name)
}
return promise(.success(boList))
}
}
}
func getProviderFuture() -> Future<[MyDTO], ProviderError> {
// should be a webservice call
let dto1 = MyDTO(id: 1, name: "one")
let dto2 = MyDTO(id: 2, name: "two")
return Future { promise in promise(.success([dto1, dto2])) }
}
我在 getManagerProvider 上有这个错误:
Instance method 'flatMap(maxPublishers:_:)' requires the types '([MyBO], ManagerError).Failure' and 'Never' be equivalent
Type '([MyBO], ManagerError)' cannot conform to 'Publisher'; only struct/enum/class types can conform to protocols
我有这样的东西,它在操场上运行良好。
为了精确起见,最好删除发布者,以便能够在不更改代码外部的情况下更改您的实现
enum DTOError: Error {
case wrongDTO
}
enum BOError: Error {
case wrongBO
}
struct DTO {
let value = "Value"
}
struct BO {
let value: String
init(dto: DTO) {
self.value = dto.value
}
}
func getDTO() -> AnyPublisher<DTO, DTOError> {
Future { promise in
promise(.success(DTO()))
}
.eraseToAnyPublisher()
}
func getBO() -> AnyPublisher<BO, BOError> {
getDTO()
.flatMap({ dto -> Future<BO, DTOError> in
Future<BO, DTOError> { promise in
promise(.success(BO(dto: dto)))
}
})
.mapError { dtoError -> BOError in
.wrongBO
}
.eraseToAnyPublisher()
}
getBO()
.sink(receiveCompletion: { completion in
print(completion)
}) { data in
print(data)
}
虽然可能有更简洁的解决方案