【问题标题】:Swift combine Convert Publisher typeSwift 结合 Convert Publisher 类型
【发布时间】:2021-07-08 08:33:14
【问题描述】:

我正在探索将 Swift 与这个项目结合起来 https://github.com/sgl0v/TMDB 我正在尝试用支持组合的东西替换它的 imageLoader:https://github.com/JanGorman/MapleBacon

该项目有一个返回类型AnyPublisher<UIImage?, Never> 的函数。 但是 imageLoader MapleBacon 库返回的类型是 AnyPublisher<UIImage, Error>

所以我正在尝试使用此函数转换类型:

func convert(_ loader: AnyPublisher<UIImage, Error>) -> AnyPublisher<UIImage?, Never> {
    // here.
}

我实际上发现了一个与我的问题有点相似的问题,但答案没有帮助: https://stackoverflow.com/a/58234908/3231194


到目前为止我所做的尝试(马特对链接问题的回答)。

示例项目有这个功能:

func loadImage(for movie: Movie, size: ImageSize) -> AnyPublisher<UIImage?, Never> {
        return Deferred { return Just(movie.poster) }
            .flatMap({ poster -> AnyPublisher<UIImage?, Never> in
                guard let poster = movie.poster else { return .just(nil) }
                let url = size.url.appendingPathComponent(poster)
                let a = MapleBacon.shared.image(with: url)
                    .replaceError(with: UIImage(named: "")!) // <----
            })
            .subscribe(on: Scheduler.backgroundWorkScheduler)
            .receive(on: Scheduler.mainScheduler)
            .share()
            .eraseToAnyPublisher()
    }

如果我这样做replaceError

我得到Publishers.ReplaceError&lt;AnyPublisher&lt;UIImage, Error&gt;&gt;的类型


但是,我能够通过扩展库来解决这个问题。

extension MapleBacon {
    public func image(with url: URL, imageTransformer: ImageTransforming? = nil) -> AnyPublisher<UIImage?, Never> {
      Future { resolve in
        self.image(with: url, imageTransformer: imageTransformer) { result in
          switch result {
          case .success(let image):
            resolve(.success(image))
          case .failure:
            resolve(.success(UIImage(named: "")))
          }
        }
      }
      .eraseToAnyPublisher()
    }
}

【问题讨论】:

  • @JoakimDanielson IDK,只是一个挑战,就像整个示例项目都有这种类型。我也想要一个可选的 UIImage 与一个 ViewModel 中带有错误发布者的 UIImage(就像在示例项目中一样)。
  • 这似乎是一个完美的复制目标。这些答案是如何解决您的问题的?
  • @DávidPásztor 查看链接问题答案中的评论。我实际上尝试过,但它似乎对我来说变得越来越复杂。我现在正在研究的一种解决方案是扩展库。
  • 你能展示你从那篇文章中尝试过的东西吗?什么“变得更复杂”了?马特的回答应该可以完成这项工作。
  • 感谢@Sweeper。请参阅我的编辑。我也添加了我当前的解决方案。

标签: ios swift combine


【解决方案1】:

首先,您需要将mapUIImage 转为UIImage?。明智的做法当然是将每个元素包装在一个可选项中。

然后,您尝试将有时会产生错误的发布者转为Never 产生错误的发布者。您replaceError(with:) 您选择的元素。您应该用什么元素替换错误?很自然的答案是nil,因为您的发布者现在发布可选图片!当然,assertNoFailure 在语法上也可以工作,但是你可能在这里下载图片,所以很可能会发生错误......

最后,我们需要通过 eraseToAnyPublisher 将其转换为 AnyPublisher

MapleBacon.shared.image(with: url)
    .map(Optional.some)
    .replaceError(with: nil)
    .eraseToAnyPublisher()

【讨论】:

  • 另外,感谢您的解释!
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2022-08-16
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多