链网络在组合中顺序调用

Phi*_* K. 5 swift combine

我的目标是使用合并来链接多个(此时为两个)网络调用,如果第一次调用失败则中断链接。

我有两种对象类型:CategoryEntitySubcategoryEntity。每个CategoryEntity都有一个称为 的属性subcategoriesIDS。第一次调用时,我需要获取所有子类别,第二次调用时,我将获取所有类别,然后创建一个CategoryEntityViewModel. CategoryEntityViewModel包含一个SubcategoryEntityViewModel基于 的CategoryEntity数组subcategoriesIDS

只是为了更清楚:

  1. 获取子类别
  2. 获取类别
  3. 为每个获取的子类别创建一个SubcategoryEntityViewModel并存储在某处
  4. CategoryEntityViewModel是为每个获取的类别创建的。CategoryEntity该对象将使用一个对象和一个数组进行初始化,并在和存储的数组SubcategoryEntityViewModel之间找到过滤匹配的 IDsubcategoriesIDSSubcategoryEntityViewModel

我现在的代码是:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

这些方法正在工作(sink在另一个类中调用,不认为它有用,所以没有复制到这里),但我找不到链接它们的正确方法。

mat*_*att 2

使用Combine 链接异步操作的方法是flatMap。在地图函数内生成第二个发布者。请务必将任何所需的信息作为值传递到地图函数中,以便第二个发布者可以使用它。有关基本示例,请参阅如何使用 Joint + Swift 复制 PromiseKit 样式的链式异步流程。


归档时间:

查看次数:

5309 次

最近记录:

4 年,10 月 前