Skip to content

Instantly share code, notes, and snippets.

@adamrothman
Last active July 14, 2017 08:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamrothman/3166d727829f1d41cd0f to your computer and use it in GitHub Desktop.
Save adamrothman/3166d727829f1d41cd0f to your computer and use it in GitHub Desktop.
Upload a UIImage to S3 and get its URL
/*
* Credit to JC https://github.com/kharmabum for most of this code.
*
* Frameworks used:
* - Alamofire https://github.com/Alamofire/Alamofire
* - Async https://github.com/duemunk/Async
* - AWS SDK http://aws.amazon.com/mobile/sdk/
*/
import Foundation
import Alamofire
import Async
import AWSCore
import AWSS3
class NetworkManager: Alamofire.Manager {
private static let AWSAccessKey = "ACCESS KEY"
private static let AWSSecret = "SECRET"
private static let AWSRegion = AWSRegionType.USWest2
private static let S3Bucket = "my-bucket"
private static let instance: NetworkManager = {
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders
return NetworkManager(configuration: configuration)
}()
var backgroundQueue: dispatch_queue_t
var awsConfigurationToken: dispatch_once_t = 0
init(configuration: NSURLSessionConfiguration) {
let attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_BACKGROUND, 0)
backgroundQueue = dispatch_queue_create("com.yourname.NetworkManager", attr)
super.init(configuration: configuration)
}
class func uploadFileWithURL(URL: NSURL, contentType: String, destination: String, completion: (Result<String, NSError>) -> Void) {
dispatch_once(&self.instance.awsConfigurationToken) {
let credentialsProvider = AWSStaticCredentialsProvider(accessKey: NetworkManager.AWSAccessKey, secretKey: NetworkManager.AWSSecret)
let configuration = AWSServiceConfiguration(region: NetworkManager.AWSRegion, credentialsProvider: credentialsProvider)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
}
Async.customQueue(self.instance.backgroundQueue) {
// unique key for the image based on the time and a random UUID
let key = "\(NSDate().timeIntervalSince1970)" + "-" + NSUUID().UUIDString
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest.key = key
uploadRequest.body = URL
uploadRequest.contentType = contentType
uploadRequest.ACL = .PublicRead
uploadRequest.bucket = NetworkManager.S3Bucket + "/" + destination
let transferManager = AWSS3TransferManager.defaultS3TransferManager()
transferManager.upload(uploadRequest).continueWithBlock { (task) -> AnyObject? in
guard task.error == nil else {
debugPrint("Failed to upload file: " + task.error.debugDescription)
Async.main() {
completion(Result.Failure(task.error!))
}
return nil
}
let imageURLString = "https://s3-us-west-2.amazonaws.com/\(NetworkManager.S3Bucket)/\(destination)/\(key)"
Async.main() { completion(Result.Success(imageURLString)) }
return nil
}
}
}
class func uploadData(data: NSData, contentType: String, destination: String, completion: (Result<String, NSError>) -> Void) {
Async.customQueue(self.instance.backgroundQueue) {
let tmpURL = NSURL(fileURLWithPath: NSTemporaryDirectory().stringByAppendingString("/" + NSUUID().UUIDString))
data.writeToURL(tmpURL, atomically: true)
uploadFileWithURL(tmpURL, contentType: contentType, destination: destination, completion: completion)
}
}
class func uploadImage(image: UIImage, completion: (Result<String, NSError>) -> Void) {
Async.customQueue(self.instance.backgroundQueue) {
if let data = UIImageJPEGRepresentation(image, 0.5) {
let contentType = "image/jpeg" // MIME type
uploadData(data, contentType: contentType, destination: "images", completion: completion)
} else {
Async.main() {
completion(Result.Failure(NSError(domain: NSURLErrorDomain, code: NSURLErrorUnknown, userInfo: nil)))
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment