gpt4 book ai didi

swift - 在Combine 中按顺序调用链式网络

转载 作者:行者123 更新时间:2023-12-04 17:22:16 25 4
gpt4 key购买 nike

我的目标是使用 Combine 链接多个(此时为两个)网络调用,如果第一次调用失败则中断链。
我有两种对象类型:CategoryEntitySubcategoryEntity .每CategoryEntity有一个名为 subcategoriesIDS 的属性.
第一次调用我需要获取所有子类别,第二次我将获取所有类别,然后我将创建一个数组 CategoryEntityViewModel .CategoryEntityViewModel包含一个数组 SubcategoryEntityViewModel基于 CategoryEntitysubcategoriesIDS .
只是为了更清楚:

  • 获取子类别
  • 获取类别
  • 创建一个 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 在另一个类中被调用,认为它没有用所以不在此处复制)但我找不到链接它们的正确方法。

    最佳答案

    使用Combine 链接异步操作的方法是flatMap .在 map 函数中生成第二个发布者。确保将任何需要的信息作为值传递给 map 函数,以便第二个发布者可以使用它。见 How to replicate PromiseKit-style chained async flow using Combine + Swift一个基本的例子。

    关于swift - 在Combine 中按顺序调用链式网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65508784/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com