我正在尝试使用 ReactiveX (RxSwift) 将多张照片上传到服务器,收集每个请求的响应,然后发出一个最终请求以完成提交。
reduce
在我尝试所有响应之前,一切似乎都运行良好。决赛subscribeNext
永远不会被调用。(也许我误解了如何flatMap
或reduce
工作?)
具体来说,这就是我尝试执行此过程的方式。
准备一个 observable 来对每张照片进行编码(
self.imageMgr
是 的一个实例PHCachingImageManager()
)func getPhotoDataObservable(asset: PHAsset) -> Observable<NSData> { return create { observer in self.imageMgr.requestImageForAsset(asset, targetSize: PHImageManagerMaximumSize, contentMode: .AspectFit, options: nil, resultHandler: { (myImage, myInfo) -> Void in let data = UIImageJPEGRepresentation(myImage!, 1.0)! NSLog("Encoded photo") observer.onNext(data) self.converts += 1 if self.converts == self.userReview.photos.count { NSLog("Completed encoding photos") observer.onCompleted() } }) return NopDisposable.instance } }
准备一个 observable 来上传每张编码后的照片(使用 Alamofire 和 RxAlamofire)
func getPostPhotoObservable(photoData: NSData) -> Observable<ReviewPhotoObject> { return create { observer in NSLog("Uploading Photo") upload(.POST, urlRequest.URLString, headers: nil, multipartFormData: { mfd in mfd.appendBodyPart(data: photoData, name: "image", fileName: "image", mimeType: "image/jpeg") }, encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): upload.responseJSON(completionHandler: { (myResponse) -> Void in if let photoResponse = myResponse.result.value { let photoObject = photoResponse.objectForKey("photo")! let photo = ReviewPhotoObject() photo.photoID = photoObject.objectForKey("id")! as! NSNumber NSLog("Uploaded Photo") observer.onNext(photo) } self.uploads += 1 if self.uploads == self.userReview.photos.count { NSLog("Completed uploading photos") observer.onCompleted() } }) case .Failure(let encodingError): observer.onError(encodingError) print(encodingError) } }) return NopDisposable.instance } }
最后,把它们放在一起
func postReview(review: MyReview) { self.userReview = review _ = review.photos.toObservable().flatMap { photos in return self.getPhotoDataObservable(photos) }.flatMap { photoData in return self.getPostPhotoObservable(photoData) }.reduce([], { var accumulator, photo: ReviewPhotoObject) -> [Int] in accumulator.append(Int(photo.photoID)) return accumulator }).subscribeNext({ (photoIds) -> Void in print(photoIds) // Never called }) }
运行时(例如 2 张照片),输出如下:
Encoded photo
Uploading photo
Encoded photo
Uploading photo
Completed encoding photos
Uploaded photo
Uploaded photo
Completed uploading photos
但subscribeNext
永远不会被调用。由于关于 RxSwift 的文档仍然有点薄,我希望这里的人能告诉我我误解了什么。