Skip to content

Instantly share code, notes, and snippets.

@LucidityDesign
Last active January 12, 2019 14:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save LucidityDesign/5ffff6408c6f7de8a87fd59c9ba8065a to your computer and use it in GitHub Desktop.
Save LucidityDesign/5ffff6408c6f7de8a87fd59c9ba8065a to your computer and use it in GitHub Desktop.
Use BrightFutures, Alamofire and Operations to queue the upload of multiple images
//
// 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
}
}