【问题标题】:Combine, retrieve array of images from array of URLs and assign them to corresponding object组合,从 URL 数组中检索图像数组并将它们分配给相应的对象
【发布时间】:2022-01-20 08:49:48
【问题描述】:

我是使用 Combine 的新手,坦率地说,我不知道这个问题是否愚蠢,无论如何我有一个发布者,然后我通过以下方式从 RESTful 操作中检索到的对象数组返回给调用者:

       let publisher = URLSession.shared.dataTaskPublisher(for: URL)
        .handleEvents(
            receiveSubscription: { _ in
                activityIndicatorPublisher.send(true)
            }, receiveCompletion: { _ in
                activityIndicatorPublisher.send(false)
            }, receiveCancel: {
                activityIndicatorPublisher.send(false)
            })
        .tryMap { data, response -> Data in
            guard let httpResponse = response as? HTTPURLResponse,
                  httpResponse.statusCode == 200 else {
                      throw NetworkError.httpError
                  }
            print(String(data: data, encoding: .utf8) ?? "")
            return data
        }
        .decode(type: [ShowElement].self, decoder: JSONDecoder())
        .flatMap { $0.publisher }
        .map(\.show?.image?.medium)
        .flatMap(maxPublishers:.max(1)) { url in
            URLSession.shared.dataTaskPublisher(for: url)
                .map(\.data)
                .replaceError(with: Data())
        }
        .map{ imageData, item -> ShowElement in
            var mutableItem = item
            mutableItem.imageData = imageData
            return mutableItem
        }
        .collect()
        .catch { error -> Just<[ShowElement]> in
            print(error)
            return Just([])
        }
        .eraseToAnyPublisher()
    return publisher
}

当我执行 dataTaskPublisher 时,我收到错误:“在调用实例方法 dataTaskPublisher 时没有完全匹配,当我执行 imageData 的映射时,我收到另一个错误:”上下文闭包类型 '(Publishers.FlatMap>, Error>, Publishers.MapKeyPath, Error>, Publishers.Decode , JSONDecoder.Input>, [ShowElement], JSONDecoder>>, String?>>.Output) -> ShowElement' (aka '(Data) -> ShowElement') 期望1 个参数,但 2 个用于闭包体"

【问题讨论】:

    标签: json swift asynchronous combine


    【解决方案1】:

    每个数组都可以用作发布者。

    假设showArray 代表[ShowElement] 对象。

    只需拨打publisher

    showArray.publisher
    

    然后将每个项目映射到其 URL

    .map(\.url) // replace `url` with the real property name
    

    然后flatMap URL 依次加载每张图片

    .flatMap(maxPublishers:.max(1)) { url in
                URLSession.shared.dataTaskPublisher(for: url)
                   .map(\.data)
                   .replaceError(with: Data())
    }
    

    然后zip的结果与对应的ShowElement

    .zip(showArray.publisher)
      
    

    然后映射结果并赋值

    .map{ (imageData, item) -> ShowElement in
           var mutableItem = item
           if let image = UIImage(data: imageData) {
              mutableItem.image = image // replace `image` with the real property name
           }
           return mutableItem
    }
    

    终于collect物品

    .collect()
    

    结果是包含图像的ShowElement 数组。

    【讨论】:

    • 嗨@vadian,谢谢你的回答,我相信它是完美的,但我发现很难理解从哪里开始将你的代码行放入我的。如果我把它们放在最后,我会收到错误,即“[ShowElement] 类型的值”没有我的属性,因为它把它当作一个数组,我不会进入数组的单个元素。
    猜你喜欢
    • 2020-01-12
    • 1970-01-01
    • 2021-11-22
    • 2021-01-17
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多