Sök…
Ladda upp en bild eller en video till S3 med AWS SDK
Innan jag börjar med exemplet skulle jag rekommendera att skapa en Singleton med en delegatklassmedlem så att du kan uppnå ett användningsfall för att ladda upp en fil i bakgrunden och låta användaren fortsätta att använda din app medan filerna laddas upp även när appen är bakgrunden.
Låt oss börja, först bör vi skapa ett enum som representerar S3-konfigurationen:
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"
}
Nu bör vi ställa in referenser när din app startas för första gången, så vi bör ställa in dem i AppDelegate
på didFinishLaunchingWithOptions
metoden (var uppmärksam på att du ska ställa in din region på 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)
}
Eftersom vi redan är inne i AppDelegate, bör vi implementera bakgrundsuppringning som hanteras av 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)
}
När användaren flyttar appen till bakgrunden kommer din överföring att fortsätta med den faktiska uppladdningen.
För att ladda upp filen med AWS SDK måste vi skriva filen till enheten och ge SDK den faktiska sökvägen. För exempelets skull, föreställ dig att vi har en UII-bild (kan vara en video också ...) och vi kommer att skriva den till en temp-mapp:
// 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 och filnamn kommer att användas för den faktiska överföringen senare.
Det finns två stängningar som vi måste definiera som tillhandahålls av AWS SDK,
-
AWSS3TransferUtilityUploadCompletionHandlerBlock
- En stängning som meddelar när överföringen är klar (eller inte) -
AWSS3TransferUtilityUploadProgressBlock
- En stängning som meddelar varje skickad byte
Om du planerar att ha en Singleton bör du definiera dessa typer som klassmedlemmar. Implementeringen ska se ut så här:
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)
}
OBS: Om du använder en Singleton kanske du vill definiera en delegat som kommer att rapportera tillbaka med framsteg eller när filen är klar. Om du inte använder en Singleton kan du skapa en statisk metod som skulle ha relevanta typer:
static func uploadImageToS3(fileURL : NSURL,
fileName : String,
progressFunctionUpdater : Float -> Void,
resultBlock : (NSError?) -> Void)
{
// Actual implementation .....
// ...
// ...
}
-
progressFunctionUpdater
- kommer att rapportera tillbaka till en funktion med framsteg. -
resultBlock
- Om du returnerar noll då uppladdningen lyckades annars skickar du felobjektet
Mina damer och herrar, den faktiska uppladdningen:
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
}
Happy S3 laddar upp :)