Last active
January 12, 2019 14:46
-
-
Save LucidityDesign/5ffff6408c6f7de8a87fd59c9ba8065a to your computer and use it in GitHub Desktop.
Use BrightFutures, Alamofire and Operations to queue the upload of multiple images
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AsynchronousOperation.swift | |
// | |
// Created by Robert Ryan on 9/20/14. | |
// Copyright (c) 2014 Robert Ryan. All rights reserved. | |
// | |
import UIKit | |
import Alamofire | |
import BrightFutures | |
import Photos | |
class UploadOperation: AsynchronousOperation { | |
let image: Image | |
var promise: Promise<Void, UploadError> | |
lazy var uploadQueue: DispatchQueue = { | |
var queue = DispatchQueue(label: "lines-upload-queue", | |
qos: DispatchQoS.background, | |
attributes: .concurrent, | |
autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, | |
target: DispatchQueue.global(qos: .background)) | |
return queue | |
}() | |
weak var request: Alamofire.Request? | |
init(image: Image, promise: Promise<Void, UploadError>) { | |
self.image = image | |
self.promise = promise | |
super.init() | |
} | |
override func main() { | |
let url = Constants.serverUrl + "/images" | |
self.getImage(image: self.image).onSuccess { (imagePath) in | |
self.uploadImage(with: imagePath, url: url).onFailure(callback: { (error) in | |
self.promise.failure(error) | |
}).onSuccess(callback: { (image) in | |
self.completeOperation() | |
self.promise.success() | |
}) | |
} | |
} | |
fileprivate func uploadImage(with imagePath: URL, url: String) -> Future<Image, UploadError> { | |
let promise = Promise<Image, UploadError>() | |
Alamofire.upload( | |
multipartFormData: { multipartFormData in | |
multipartFormData.append(imagePath, withName: "image", fileName: "image.jpg", mimeType: "image/jpeg") | |
}, | |
to: url, | |
encodingCompletion: { [weak self] encodingResult in | |
switch encodingResult { | |
case .success(let upload, _, _): | |
guard let strongSelf = self else {return} | |
upload.responseSwiftyJSON(queue: strongSelf.uploadQueue, completionHandler: { response in | |
if response.result.isSuccess { | |
promise.success() | |
} else { | |
promise.failure(UploadError.connectionError(error: response.result.error)) | |
} | |
}) | |
case .failure(let encodingError): | |
promise.failure(UploadError.connectionError(error: encodingError)) | |
} | |
} | |
) | |
return promise.future | |
} | |
fileprivate func getImage(image: Image) -> Future<URL, UploadError> { | |
let promise = Promise<URL, UploadError>() | |
if let localId = image.localId { | |
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localId], options: nil) | |
if(fetchResult.count < 1) { | |
// promise.failure(UploaderError...) | |
} else { | |
let asset = fetchResult.firstObject | |
let resource = PHAssetResource.assetResources(for: asset!).first | |
let filename = resource?.originalFilename | |
let pathToWrite = NSTemporaryDirectory() + filename! | |
let localPath = URL(fileURLWithPath: pathToWrite) | |
let requestOptions = PHImageRequestOptions() | |
requestOptions.isSynchronous = true | |
requestOptions.resizeMode = PHImageRequestOptionsResizeMode.fast | |
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryMode.fastFormat | |
Variables.imageManager.requestImage(for: asset, | |
targetSize: CGSize(width: size.width , height: size.height), | |
contentMode: PHImageContentMode.aspectFill, | |
options: requestOptions, | |
resultHandler: { (localImage, _) -> Void in | |
if let localImage = localImage { | |
let imageData = Functions.imageToJpegData(image: localImage, quality: 0.65) | |
FileManager.default.createFile(atPath: pathToWrite, contents: imageData, attributes: nil) | |
promise.success(localPath) | |
} else { | |
// promise.failure(UploaderError...) | |
} | |
}) | |
} | |
} else { | |
// promise.failure(UploaderError...) | |
} | |
return promise.future | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Modification of Robert Ryan's code: https://stackoverflow.com/questions/27021896/nsurlsession-concurrent-requests-with-alamofire/27022598#27022598
See https://medium.com/@linesapp/use-brightfutures-alamofire-and-operations-to-queue-the-upload-of-multiple-images-23facd3b44f for a description