Swift 在联合收割机中按顺序进行链网络调用

Swift 在联合收割机中按顺序进行链网络调用,swift,combine,Swift,Combine,我的目标是使用Combine链接多个(此时两个)网络调用,如果第一个调用失败,则断开链 我有两种对象类型:CategoryEntity和SubcategoryEntity。每个CategoryEntity都有一个名为subcategoriesIDS的属性。 第一次调用我需要获取所有子类别,第二次调用我将获取所有类别,然后我将创建一个CategoryEntityViewModel数组。 CategoryEntityViewModel包含基于CategoryEntityViewModel的子类别ID

我的目标是使用Combine链接多个(此时两个)网络调用,如果第一个调用失败,则断开链

我有两种对象类型:
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函数中,以便第二个发布者可以使用它。有关基本示例,请参见。

    另请参见