【发布时间】:2020-12-30 14:44:49
【问题描述】:
我的目标是使用 Combine 链接多个(此时为两个)网络调用,如果第一次调用失败则断开链接。
我有两种对象类型:CategoryEntity 和 SubcategoryEntity。每个CategoryEntity 都有一个名为subcategoriesIDS 的属性。
第一次调用我需要获取所有子类别,第二次我将获取所有类别,然后我将创建一个CategoryEntityViewModel 的数组。
CategoryEntityViewModel 包含一个基于CategoryEntity 的subcategoriesIDS 的SubcategoryEntityViewModel 数组。
为了更清楚:
- 获取子类别
- 获取类别
- 为每个提取的子类别创建一个
SubcategoryEntityViewModel并存储在某处 -
CategoryEntityViewModel是为每个提取的类别创建的。此对象将使用CategoryEntity对象和SubcategoryEntityViewModel数组进行初始化,发现过滤subcategoriesIDS之间的匹配ID 并存储SubcategoryEntityViewModel数组
我现在的代码是:
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 在另一个类中被调用,不认为它有用所以这里没有复制)但是我找不到正确的方法来链接它们。
【问题讨论】: