【问题标题】:Input and output type mismatch in Combine data fetching组合数据提取中的输入和输出类型不匹配
【发布时间】:2020-06-18 06:52:10
【问题描述】:

我是响应式编程和组合的新手,我有以下从 API 获取天气数据的方法。

  • 首先,我检查如果我得到 200,如果没有,则抛出一个错误。
  • 如果我得到正确的数据,我将通过 JSONDecoder 对其进行解码,但只是为了 检查 JSON 解码是否有问题我正在返回默认对象。
  • 终于映射了抛出的错误 第一步,但我在 flatMAP 函数中收到以下错误 实例方法

flatMap(maxPublishers:_:)' 要求类型“Publishers.TryMap.Failure”(又名“Error”)和“Just.Failure”(又名“Never”)是等效的

private func fetchDataFor(urlStr: String) -> AnyPublisher<WeatherData, Error> {
            let url = URL(string: urlStr)!
            return URLSession.shared.dataTaskPublisher(for: url)
                .tryMap({ (data, response)  in
                    let response = (response as? HTTPURLResponse)
                    if response?.statusCode != 200 {
                        throw NSError(domain: "Error", code: response!.statusCode, userInfo: .none)
                    }
                    return data
            })
            .flatMap{ data in
                Just(data)
                    .decode(type: WeatherData.self, decoder: JSONDecoder())
                    .catch{ error in
                        return Just(defaultWeatherData)
                    }
            }
            .mapError{ error in
                return error
            }
            .receive(on: RunLoop.main)
            .eraseToAnyPublisher()
        }

有人可以指导这里出了什么问题,或者我使用了一些错误的方法。谢谢

【问题讨论】:

    标签: ios swift reactive-programming combine flatmap


    【解决方案1】:

    把你的函数改成这样:

    private func fetchDataFor(urlStr: String) -> AnyPublisher<WeatherData, Error> {
        let url = URL(string: urlStr)!
        return URLSession.shared.dataTaskPublisher(for: url)
            .tryMap({ (data, response)  in
                let response = (response as? HTTPURLResponse)
                if response?.statusCode != 200 {
                    throw NSError(domain: "Error", code: response!.statusCode, userInfo: .none)
                }
                return data
            })
            .decode(type: WeatherData.self, decoder: JSONDecoder())
            .receive(on: RunLoop.main)
            .eraseToAnyPublisher()
    }
    

    Combine 具有有用的内置 .decode 方法,您可以在其中将数据转换为本地模型。

    另外,一个好的做法是不要在请求方法中使用.receive(on: RunLoop.main),而是让您的 ViewModel/Interactor(只是响应的消费者)决定它想要接收响应的线程。

    【讨论】:

    • 您好,谢谢,实际上我有这个实现,然后我想检查在 JSON 解析期间是否存在一些解析问题,然后我想获取默认对象。请记住,我用 flatmap 编写了函数
    • 此外,此 mapError 对应于 FlatMap 或 tryMap 或事件链中发生的任何错误。
    • 你可以用这个替换你的 flatMap: .flatMap { Just(data).decode(type: WeatherData.self, decoder: JSONDecoder()) .catch { 错误返回 Just( defaultWeatherData) .setFailureType(to: Error.self) .eraseToAnyPublisher() } }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 2021-03-21
    • 2021-11-24
    相关资源
    最近更新 更多