Last active
July 14, 2017 08:33
-
-
Save adamrothman/3166d727829f1d41cd0f to your computer and use it in GitHub Desktop.
Upload a UIImage to S3 and get its URL
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
/* | |
* 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