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 AppDelegatedidFinishLaunchingWithOptions 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,

  1. AWSS3TransferUtilityUploadCompletionHandlerBlock - En stängning som meddelar när överföringen är klar (eller inte)
  2. 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 .....
 //    ...
 //    ...
}
  1. progressFunctionUpdater - kommer att rapportera tillbaka till en funktion med framsteg.
  2. 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 :)



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow