Swift 在联合收割机中按顺序进行链网络调用
我的目标是使用Combine链接多个(此时两个)网络调用,如果第一个调用失败,则断开链 我有两种对象类型:Swift 在联合收割机中按顺序进行链网络调用,swift,combine,Swift,Combine,我的目标是使用Combine链接多个(此时两个)网络调用,如果第一个调用失败,则断开链 我有两种对象类型:CategoryEntity和SubcategoryEntity。每个CategoryEntity都有一个名为subcategoriesIDS的属性。 第一次调用我需要获取所有子类别,第二次调用我将获取所有类别,然后我将创建一个CategoryEntityViewModel数组。 CategoryEntityViewModel包含基于CategoryEntityViewModel的子类别ID
CategoryEntity
和SubcategoryEntity
。每个CategoryEntity
都有一个名为subcategoriesIDS
的属性。
第一次调用我需要获取所有子类别,第二次调用我将获取所有类别,然后我将创建一个CategoryEntityViewModel
数组。
CategoryEntityViewModel
包含基于CategoryEntityViewModel
的子类别ID的子类别ViewModel
数组
更清楚地说:
获取子类别
获取类别
为每个获取的子类别创建一个子类别EntityViewModel
,并将其存储在某处
为获取的每个类别创建CategoryEntityViewModel
。此对象将使用类别实体
对象和子类别实体视图模型
数组初始化,在子类别ID
和存储的子类别实体视图模型
数组之间找到筛选匹配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()
}
}
类分类服务:服务,ErrorManager{
静态let shared=CategoriesService()
内部let解码器=JSONDecoder()
@已发布的变量错误:ServerError=.none
私有init(){
decoder.dateDecodingStrategyFormatters=[DateFormatter.yearMonthDay]
}
func getAllCategories()->AnyPublisher{
let request=self.createRequest(带URLString:\(AppSettings.api\u endpoint)/categories/all),forMethod:.get)
返回URLSession.shared.dataTaskPublisher(用于:请求)
.receive(在:DispatchQueue.main上)
.tryMap{data,response->data in
guard let httpResponse=响应为?HTTPURLResponse,200..ServerError in self.manageError(error:error)}
.receive(打开:RunLoop.main)
.删除任何发布者()
}
func getAllSubcategories()->AnyPublisher{
let request=self.createRequest(带URLString:\(AppSettings.api\u endpoint)/subcategories/all),forMethod:.get)
返回URLSession.shared.dataTaskPublisher(用于:请求)
.receive(在:DispatchQueue.main上)
.tryMap{data,response->data in
guard let httpResponse=响应为?HTTPURLResponse,200..ServerError in self.manageError(error:error)}
.receive(打开:RunLoop.main)
.删除任何发布者()
}
}
这些方法正在工作(sink
在另一个类中调用,不要认为它有用,所以不要复制到这里),但我找不到链接它们的正确方法。使用Combine链接异步操作的方法是flatMap
。在映射函数中生成第二个发布者。确保将任何需要的信息作为值向下传递到map函数中,以便第二个发布者可以使用它。有关基本示例,请参见。另请参见