ios - 使用响应式编程将具有 imageURL 的对象转换为具有下载的 UIImage 的对象

标签 ios swift reactive-programming rx-swift reactive-swift

我有一个 A 对象数组。我想将其转换为包含 B 类型对象的数组。但棘手的部分是同时下载图像并使用 RxSwift 或 ReactiveSwift 完成所有操作。你有什么建议我该怎么做吗?

struct A {
  let name: String
  let imageURL: URL
  let thumbnailURL: URL
}

struct B {
  let name: String
  let image: UIImage?
  let thumbnail: UIImage?
}

最佳答案

因此,尽管我对这可能非常重要的上下文进行了评论,但以下是我如何使用 ReactiveSwift 将 [A] 异步转换为 [B]。请注意,我还没有机会测试这段代码,但它应该涵盖基本思想:

// This function takes an `NSURL` and creates an asynchronous `SignalProducer` to
// download an image from that URL or yields `nil` if there is an error.
func downloadImage(url: URL) -> SignalProducer<UIImage?, NoError> {
    let request = URLRequest(url: url)
    return URLSession.shared.reactive.data(with: request)
        .map { (data, response) -> UIImage? in UIImage(data: data) }
        .flatMapError { _ in SignalProducer<UIImage?, NoError>(value: nil) }
}

func convertAToB(_ a: A) -> SignalProducer<B, NoError> {
    let imgDownload = downloadImage(url: a.imageURL)
    let thumbDownload = downloadImage(url: a.thumbnailURL)
    return SignalProducer<UIImage?, NoError>.combineLatest(imgDownload, thumbDownload)
        .map { images in
            return B(name: a.name, image: images.0, thumbnail: images.1)
        }
}

func convertAllAsToBs(_ inputs: [A]) -> SignalProducer<[B], NoError> {
    return SignalProducer<A, NoError>(values: inputs)
        .flatMap(.concat, convertAToB)
        .collect()
}


let inputs: [A] = ...

convertAllAsToBs(inputs).startWithValues { outputs in
    // `outputs` is [B]
}

编辑:

为了使这个答案与 @PhilippeC 的 RxSwift 答案相同,这里总结了每个 ReactiveSwift 运算符所做的事情:

  • SignalProducer.init(values:) 相当于 RxSwift 的 Observable.from。它创建一个生产者,将序列的每个值作为单独的事件发送。
  • collect 相当于 RxSwift 的 toArray。它从源生产者收集每个值,并在源生产者完成后将它们发送到单个数组中。
  • flatMap 为每个传入的 A 启动 convertAToB 生产者,并根据指定的 FlattenStrategy 合并结果。在本例中,我使用了 .concat,这使其相当于 RxSwift 的 concatMap,它连接每个结果并保留 @PhilippeC 在其答案中描述的顺序。

关于ios - 使用响应式编程将具有 imageURL 的对象转换为具有下载的 UIImage 的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50203876/

相关文章:

objective-c - 即使在 alloc/init 之后,我的 NSMutableArray 也会在函数范围之外丢失它的对象

ios - 初始化程序不会在 swift 中从其父类(super class)错误中覆盖设计的初始化程序

java - Vertx Future 不会等待

python - 分区的 Observable 第二个流从未到达

c# - 接收 : how to pass the latest value from observable into ReactiveCommand

ios - 无法使用 double 类型的左值初始化 'id _NonNull' 类型的参数

ios - iOS 7+ 上从 BGRA 字节获取 CVPixelBufferRef 的最快方法

ios - 如何在 iOS swift 中使用 sunlubo/SwiftFFmpeg 库?

ios - 如何向已有的 Storyboard添加后退按钮和导航栏?

Swift Dictionary<String, Any> 获取可选值