我的目标是用Combine连接多个(此时两个(网络调用,如果第一个调用失败,则断开连接。
我有两种对象类型:CategoryEntity
和SubcategoryEntity
。每个CategoryEntity
都有一个称为subcategoriesIDS
的性质。第一次调用需要获取所有子类别,第二次调用将获取所有类别,然后创建一个CategoryEntityViewModel
数组。CategoryEntityViewModel
包含一个基于CategoryEntity
的subcategoriesIDS
的SubcategoryEntityViewModel
数组。
更清楚一点:
- 获取子类别
- 提取类别
- 为每个提取的子类别创建一个
SubcategoryEntityViewModel
并存储在某个位置 - 为提取的每个类别创建CCD_ 11。此对象将使用
CategoryEntity
对象和SubcategoryEntityViewModel
数组进行初始化,在subcategoriesIDS
和存储的SubcategoryEntityViewModel
数组之间筛选匹配ID
我现在的代码是:
class CategoriesService: Service, ErrorManager {
static let shared = CategoriesService()
internal let decoder = JSONDecoder()
@Published var error: ServerError = .none
private init() {
decoder.dateDecodingStrategyFormatters = [ DateFormatter.yearMonthDay ]
}
func getAllCategories() -> AnyPublisher<[CategoryEntity], ServerError> {
let request = self.createRequest(withUrlString: "(AppSettings.api_endpoint)/categories/all", forMethod: .get)
return URLSession.shared.dataTaskPublisher(for: request)
.receive(on: DispatchQueue.main)
.tryMap { data, response -> Data in
guard let httpResponse = response as? HTTPURLResponse, 200..<300 ~= httpResponse.statusCode else {
switch (response as! HTTPURLResponse).statusCode {
case (401):
throw ServerError.notAuthorized
default:
throw ServerError.unknown
}
}
return data
}
.map { $0 }
.decode(type: NetworkResponse<[CategoryEntity]>.self, decoder: self.decoder)
.map { $0.result}
.mapError { error -> ServerError in self.manageError(error: error)}
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
func getAllSubcategories() -> AnyPublisher<[SubcategoryEntity], ServerError> {
let request = self.createRequest(withUrlString: "(AppSettings.api_endpoint)/subcategories/all", forMethod: .get)
return URLSession.shared.dataTaskPublisher(for: request)
.receive(on: DispatchQueue.main)
.tryMap { data, response -> Data in
guard let httpResponse = response as? HTTPURLResponse, 200..<300 ~= httpResponse.statusCode else {
switch (response as! HTTPURLResponse).statusCode {
case (401):
throw ServerError.notAuthorized
default:
throw ServerError.unknown
}
}
return data
}
.map { $0 }
.decode(type: NetworkResponse<[SubcategoryEntity]>.self, decoder: self.decoder)
.map { $0.result }
.mapError { error -> ServerError in self.manageError(error: error)}
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
}
这些方法正在工作(sink
是在另一个类中调用的,不认为它有用,所以不复制到这里(,但我找不到链接它们的正确方法。
使用Combine链接异步操作的方法是flatMap
。在map函数中生成第二个发布者。请确保将任何需要的信息作为值传递到map函数中,以便第二个发布者可以使用它。有关基本示例,请参阅如何使用Combine+Swift复制PromiseKit风格的链式异步流。