gpt4 book ai didi

ios - 为什么我不能在这个支持 ReactiveSwift 的网络工作流中观察事件?

转载 作者:行者123 更新时间:2023-11-28 06:07:26 26 4
gpt4 key购买 nike

我正在训练自己使用 ReactiveSwift用于网络和一个很好的用例似乎是从 Google Places API for iOS 获取某个位置的照片.

流程如下:

  1. 从 Google 地点 ID 获取 GMSPlacePhotoMetadata 列表
  2. 对于每个元数据,获取一张图片
  3. 将所有图片连接成一个数组

我以我能想到的最好的 ReactiveSwift 方式编写了执行此工作流的代码(参见下面的代码),但是当我调用我的服务时,尽管对 Google Places API 的所有 API 调用都已完成,但我没有进入观察部分。我觉得我从框架中遗漏了一些非常基本的东西,而且我一路上失去了一些观察者,但我无法指出问题所在。我们非常欢迎任何帮助。

我的服务代码

import Foundation
import ReactiveSwift
import GooglePlaces

struct GooglePlacesPhotoService {
func findPlacePictures(googlePlaceID: String) -> SignalProducer<[UIImage], DataStoreError> {
return findPlacePicturesMetadata(googlePlaceID: googlePlaceID)
.map { (metadata) -> SignalProducer<UIImage, DataStoreError> in
debugPrint("Mapping metadata to SignalProducer for metadata: ", metadata)
return self.findPlacePicture(metadata: metadata)
} // After mapping, we have a SignalProducer of SignalProducer<UIImage>
.flatten(.merge) // After flatening, we get a single SignalProducer<UIImage>
.reduce([], { (imageArray: [UIImage], newImage: UIImage) -> [UIImage] in
debugPrint("Merging another picture")
return imageArray + [newImage]
}) // Now we have an array of UIImage
}

private func findPlacePicturesMetadata(googlePlaceID: String) -> SignalProducer<GMSPlacePhotoMetadata, DataStoreError> {
return SignalProducer<GMSPlacePhotoMetadata, DataStoreError> { observer, disposable in
GMSPlacesClient.shared().lookUpPhotos(forPlaceID: googlePlaceID) { photos, error in
guard error == nil else { return observer.send(error: .externalError(error!)) }
guard let photos = photos else { return }

photos.results.forEach { metadata in
debugPrint("Sending metadata value: ", metadata)
observer.send(value: metadata)
}
}
}
}

private func findPlacePicture(metadata: GMSPlacePhotoMetadata) -> SignalProducer<UIImage, DataStoreError> {
return SignalProducer<UIImage, DataStoreError> { observer, disposable in
let screenSize = UIScreen.main.bounds.size
let screenScale = UIScreen.main.scale

let myCallback: GMSPlacePhotoImageResultCallback = { image, error in
guard error == nil else {
print("ERROR: couln't load picture for metadata \(metadata)")
observer.send(error: .externalError(error!))
return
}

guard let image = image else {
print("ERROR: empty image returned")
observer.send(error: .unknownExternalError)
return
}

debugPrint("Got 1 picture from metadata: ", metadata)
observer.send(value: image)
}

GMSPlacesClient.shared().loadPlacePhoto(metadata,
constrainedTo: screenSize,
scale: screenScale,
callback: myCallback)
}
}
}

我的观察代码

    googlePlaceIDProperty.signal
.filter { $0.isPresent }
.flatMap(.latest) { googlePlaceID in
return GooglePlacesPhotoService().findPlacePictures(googlePlaceID: googlePlaceID!)
}.observe { event in
debugPrint("Signal event!") // I NEVER GET THERE
switch event {
case let .value(pictures):
// Do stuff
case let .failed(error):
// Do stuff
default:
break
}
}

我的日志

"Sending metadata value: " <GMSPlacePhotoMetadata: 0x60000645f4d0>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x60000645f4d0>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x60000645b1b0>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x60000645b1b0>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x60000645b0f0>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x60000645b0f0>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x600006459950>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x600006459950>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x60000644e730>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x60000644e730>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x60000645ef30>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x60000645ef30>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x6000066420a0>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x6000066420a0>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x600006448d60>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x600006448d60>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x600006642130>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x600006642130>
"Sending metadata value: " <GMSPlacePhotoMetadata: 0x6000066421f0>
"Mapping metadata to SignalProducer for metadata: " <GMSPlacePhotoMetadata: 0x6000066421f0>
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x60000645f4d0>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x60000645b1b0>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x60000645b0f0>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x600006459950>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x60000644e730>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x60000645ef30>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x6000066420a0>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x600006448d60>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x600006642130>
"Merging another picture"
"Got 1 picture from metadata: " <GMSPlacePhotoMetadata: 0x6000066421f0>
"Merging another picture"

最佳答案

The Event contract表示它只会因失败、完成或中断的事件而终止。因此,您需要确保在发送所有值后在 SignalProducer 闭包中调用 observer.sendCompleted()

The documentation for reduce说它返回一个“在 self 完成时发送最终结果的生产者”,这意味着在完成的事件发生之前,结果永远不会被发送。基本上,除非您的 SignalProducers 明确发送一个完成的事件以指示它们没有更多的值要发送,否则它无法知道它已收集所有结果。插图很好on this graph .

因此,在您的情况下,在 findPlacePicture 中,您应该在获得预期结果后调用 sendCompleted(),即:

observer.send(value: image)
observer.sendCompleted() // <- That's the line to add.

findPlacePicturesMetadata 中:

photos.results.forEach { metadata in
debugPrint("Sending metadata value: ", metadata)
observer.send(value: metadata)
}
observer.sendCompleted() // <- That's the line to add.

关于ios - 为什么我不能在这个支持 ReactiveSwift 的网络工作流中观察事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47830359/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com