【问题标题】:Swift URLSession and Combine json array decode failsSwift URLSession 和 Combine json 数组解码失败
【发布时间】:2022-12-31 09:21:05
【问题描述】:

好吧,就像标题说的那样,我在响应服务上调用了一个 JSON 数组,但我找不到使用 Combine 解码的方法: URLSession.shared.dataTaskPublisher

客服回复:https://codebeautify.org/alleditor/y228809f7

我的请求代码:

public func getGasStationDiscounts(requestModel: GasStationDiscountsRequestDomainModel) -> CiMAObservable<GasStationDiscountsDomainModel> {
    guard let url = URL(string: RepositoryConstants.baseURL + String(format: RepositoryConstants.EndPoints.gasStationDiscounts, requestModel.gasStationID)) else {
        return Fail(error: NSError(domain: "URL Invalid", code: 001, userInfo: nil)).eraseToAnyPublisher()
    }
    
    var urlRequest = URLRequest(url: url)
    urlRequest.httpMethod = "GET"
    urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
    urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
    
    return URLSession.shared.dataTaskPublisher(for: urlRequest)
        .map(\.data)
        .decode(type: GasStationDiscountsDataModel.self, decoder: JSONDecoder())
        .map { model -> GasStationDiscountsDomainModel in
            model.parseToDomainModel()
        }.eraseToAnyPublisher()
}

解码文件:https://codebeautify.org/alleditor/y2296aefe

所以恢复,我的问题是尝试解码它,因为它是一个数组,在我的项目中,我正在使用不同的层,如数据、域和演示(不要问架构因为是一个新的,GitHub 上的 CiMA)它是混合毒蛇拱门。

提前致谢!

编辑:解决了!所以最后我找到了一个不会破坏我的架构的解决方案。 所以这里是可解码文件的小改动:https://codebeautify.org/alleditor/y22ad811e

以及请求的最后更改:

    public func getGasStationDiscounts(requestModel: GasStationDiscountsRequestDomainModel) -> CiMAObservable<GasStationDiscountsDomainModel> {
    guard let url = URL(string: RepositoryConstants.baseURL + String(format: RepositoryConstants.EndPoints.gasStationDiscounts, requestModel.gasStationID)) else {
        return Fail(error: NSError(domain: "URL Invalid", code: 001, userInfo: nil)).eraseToAnyPublisher()
    }
    
    var urlRequest = URLRequest(url: url)
    urlRequest.httpMethod = "GET"
    urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
    urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
    
    return URLSession.shared.dataTaskPublisher(for: urlRequest)
        .map(\.data)
        .decode(type: [GasStationDiscountsDataModel].self, decoder: JSONDecoder())
        .map { model -> GasStationDiscountsDomainModel in
            let stationDiscountsDomainModel = model.map { model -> StationDiscountDomainModel in
                model.parseToDomainModel()
            }
            return GasStationDiscountsDomainModel(stationDiscounts: stationDiscountsDomainModel)
        }
        .mapError { error in
            print(error.localizedDescription)
            return error
        }.eraseToAnyPublisher()
}

【问题讨论】:

    标签: json swift combine urlsession decodable


    【解决方案1】:

    响应似乎是一个数组。没有顶级元素。采用:

    .decode(type: [StationDiscountDataModel].self, decoder: JSONDecoder())
    

    【讨论】:

    • 嗯,如果你看到我的代码我仍然没有工作我有一个 model.parseToDomainModel() 我需要它因为它使用不同的层数据(存储库)域(业务)
    • @coden0w “仍然没有工作”是什么意思?你的问题是关于解码的,是吗?解码为你的结构数组对我有用。至少对我来说,将其映射到所需的输出似乎非常简单。
    • 我最终解决了它,我将在几分钟内添加解决方案。谢谢你 burnsi! (为了快速回答我的问题 :))
    • @coden0w 如果此答案帮助您解决了问题,请考虑将其标记为已接受的答案(绿色复选标记)。
    • 完毕!是的帮助了我!
    【解决方案2】:

    创建自定义运算符是这样的:

     extension Publisher where Output == Data {
        func customOperator() -> AnyPublisher<GasStationDiscountsDataModel, Never>  {
           return Just(GasStationDiscountsDataModel(data: self as! Data))
                  .eraseToAnyPublisher()
           }
     }
    

    然后使用它:

     return URLSession.shared.dataTaskPublisher(for: urlRequest)
        .map(.data)
        .customOperator()
        .map { model -> GasStationDiscountsDomainModel in
            model.parseToDomainModel()
        }.eraseToAnyPublisher()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      • 2020-04-15
      • 1970-01-01
      相关资源
      最近更新 更多