使用 AWS SDK 将图像或视频上传到 S3
在开始使用示例之前,我建议创建一个带有委托类成员的 Singleton,这样你就可以实现在后台上传文件的用例,让用户在上传文件时继续使用你的应用程序,即使应用程序也是如此是背景。
让我们开始吧,首先,我们应该创建一个代表 S3 配置的枚举:
enum S3Configuration : String
{
case IDENTITY_POOL_ID = "YourIdentityPoolId"
case BUCKET_NAME = "YourBucketName"
case CALLBACK_KEY = "YourCustomStringForCallBackWhenUploadingInTheBackground"
case CONTENT_TYPE_IMAGE = "image/png"
case CONTENT_TYPE_VIDEO = "video/mp4"
}
现在,我们应该在你的应用首次启动时设置凭据,因此,我们应该在 AppDelegate
的 didFinishLaunchingWithOptions
方法中设置它们(注意你应该在 regionType
param 设置你的区域):
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
let credentialProvider = AWSCognitoCredentialsProvider(regionType: .EUWest1, identityPoolId: S3Configuration.IDENTITY_POOL_ID.rawValue)
let configuration = AWSServiceConfiguration(region: .EUWest1, credentialsProvider: credentialProvider)
AWSS3TransferUtility.registerS3TransferUtilityWithConfiguration(configuration, forKey: S3Configuration.CALLBACK_KEY.rawValue)
}
由于我们已经在 AppDelegate 中,因此我们应该实现 AWS SDK 处理的后台回调:
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)
{
// Will print the identifer you have set at the enum: .CALLBACK_KEY
print("Identifier: " + identifier)
// Stores the completion handler.
AWSS3TransferUtility.interceptApplication(application,
handleEventsForBackgroundURLSession: identifier,
completionHandler: completionHandler)
}
现在,当用户将应用程序移至后台时,你的上传将继续实际上传。
为了使用 AWS SDK 上传文件,我们必须将文件写入设备并为 SDK 提供实际路径。为了举例,假设我们有一个 UIImage(也可能是一个视频..),我们将它写入临时文件夹:
// Some image....
let image = UIImage()
let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(fileName)
let filePath = fileURL.path!
let imageData = UIImageJPEGRepresentation(image, 1.0)
imageData!.writeToFile(filePath, atomically: true)
FileURL 和 fileName 将在稍后用于实际上传。
我们将需要定义两个由 AWS SDK 提供的闭包,
AWSS3TransferUtilityUploadCompletionHandlerBlock
- 一个关闭,通知上次完成(或不完成)AWSS3TransferUtilityUploadProgressBlock
- 一个闭包,通知发送的每个字节
如果你打算使用 Singleton,则应将这些类型定义为类成员。实现应如下所示:
var completionHandler : AWSS3TransferUtilityUploadCompletionHandlerBlock? =
{ (task, error) -> Void in
if ((error) != nil)
{
print("Upload failed")
}
else
{
print("File uploaded successfully")
}
}
var progressBlock : AWSS3TransferUtilityUploadProgressBlock? =
{ [unowned self] (task, bytesSent:Int64, totalBytesSent:Int64, totalBytesExpectedToSend:Int64) -> Void in
let progressInPercentage = Float(Double(totalBytesSent) / Double(totalBytesExpectedToSend)) * 100
print(progressInPercentage)
}
注意: 如果你使用的是 Singleton,则可能需要定义一个委托,该委托将报告进度或文件完成时。如果你不使用 Singleton,则可以创建具有相关类型的静态方法:
static func uploadImageToS3(fileURL : NSURL,
fileName : String,
progressFunctionUpdater : Float -> Void,
resultBlock : (NSError?) -> Void)
{
// Actual implementation .....
// ...
// ...
}
progressFunctionUpdater
- 将向具有进展的功能报告。resultBlock
- 如果你返回 nil 然后上传成功,你发送错误对象
女士们,先生们,实际上传:
let fileData = NSData(contentsOfFile: fileURL.relativePath!)
let expression = AWSS3TransferUtilityUploadExpression()
expression.uploadProgress = progressBlock
let transferUtility = AWSS3TransferUtility.S3TransferUtilityForKey(S3Configuration.CALLBACK_KEY.rawValue)
transferUtility?.uploadData(fileData!,
bucket: S3Configuration.BUCKET_NAME.rawValue,
key: fileName,
contentType: S3Configuration.CONTENT_TYPE_IMAGE.rawData,
expression: expression,
completionHander: completionHandler).continueWithBlock
{ (task : AWSTask) -> AnyObject? in
if let error = task.error
{
print(error)
}
if let exception = task.exception
{
print("Exception: " + exception.description)
}
if let uploadTask = task.result as? AWSS3TransferUtilityUploadTask
{
print("Upload started...")
}
return nil
}
快乐 S3 上传:)