使用 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 上傳:)