AWS S3服務

寫在開頭

最近工程中做了一個視頻上傳的相關需求,使用了亞馬遜AWS S3服務作爲存儲,關於IOS的資料比較少,也填了不少坑,這裏總結一下:

S3服務

Amazon Simple Storage Service (Amazon S3) 是一種對象存儲服務,提供行業領先的可擴展性、數據可用性、安全性和性能。自己去查官網吧:https://aws.amazon.com/cn/s3/

 

S3身份認證

關於身份認證,有兩種方法進行認證,Cognito認證和使用key進行登錄認證

1、S3推薦使用Cognito,這個方法認證使用比較簡單,但是要求在官網上進行更多的配置,如果配置不合理,上傳時會有錯誤

關於官網的具體配置參考:https://www.youtube.com/watch?v=dRAT5wT8xoE

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSWest2  identityPoolId:@"PoolId"];

    AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSWest2 credentialsProvider:credentialsProvider];

    [AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
    
    return YES;
}

2、使用accessKey、secretKey進行身份認證。這個又可以區分使用永久性的key和臨時性的key分別進行認證

//永久性的accessKey、secretKey
AWSStaticCredentialsProvider *credentialsProvider = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:accessKey secretKey:secretKey];


//臨時性的accessKey、secretKey,需要增加一個參數sessionToken
AWSBasicSessionCredentialsProvider *credentialsProvider = [[AWSBasicSessionCredentialsProvider alloc] initWithAccessKey:accessKey secretKey:secretKey sessionToken:sessionToken];

AWSEndpoint *endPoint = [[AWSEndpoint alloc] initWithURLString:@"https://s3-us-west-2.amazonaws.com"];

AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSWest2 endpoint:endPoint credentialsProvider:credentialsProvider];

[AWSS3TransferUtility registerS3TransferUtilityWithConfiguration:configuration forKey:@"LoftyApp"];

S3上傳

接下來就是上傳服務,上傳主要有四個參數

(1)因爲上傳的是視頻,使用了uploadData,根據視頻本地的路徑地址生成NSData,也可以用uploadFile

(2)bucket: 這裏只能傳桶名稱,不能把路徑拼接在後面(安卓是可以把路徑拼接在這裏,IOS就出錯)

(3)key: 這裏輸入的是文件名,文件名稱錢可以拼接路徑名稱,如:@"listing/IOStest0000003.mp4",這裏的listing是桶中的文件夾名稱,.mp4後綴名稱也是必須的,用來區分文件類型

(4)contentType:這裏傳的參數是文件類型,text/plain或者video/mp4,但是吧,其實這裏的這個類型並不重要,上傳後還是根據文件名稱的後綴來區分類型,所以(敲小黑板),文件名一定要有後綴名稱

 

AWSS3TransferUtilityUploadExpression * expression = [AWSS3TransferUtilityUploadExpression new];
    expression.progressBlock = ^(AWSS3TransferUtilityTask * _Nonnull task, NSProgress * _Nonnull progress) {
        NSLog(@"expression==上傳進度");
        NSLog(@"上傳進度=%f",progress.fractionCompleted);
    };
    
    AWSS3TransferUtilityUploadCompletionHandlerBlock completionHandler = ^(AWSS3TransferUtilityUploadTask *task, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            // Do something e.g. Alert a user for transfer completion.
            // On failed uploads, `error` contains the error object.
            
            NSLog(@"uploadFile");
            
            NSLog(@"error == %@",error);
            
            NSLog(@"task.request == %@",task.request);
            
            if(error) {
                NSLog(@"Failed to Upload");
            }else{
                
                //成功之後:視頻的url地址 在aws控制檯是固定的
                NSString * aws_mp4_url = [NSString stringWithFormat:@"https://s3-us-west-2.amazonaws.com/%@/%@",videoParameter.bucketName,videoParameter.keyName]; //上傳成功的視頻url
                NSLog(@"%@",aws_mp4_url);
                
                NSLog(@"Successfully Uploaded");
                
            }
        });
    };

    NSData *uploadData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:videoParameter.videoString]];

    //Cognito認證方法初始化
    AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility];

    //accessKey、secretKey認證初始化
    AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility S3TransferUtilityForKey:@"LoftyApp"];//與上面註冊的名稱要一致

    [[transferUtility uploadData:uploadData
                          bucket:videoParameter.bucketName
                             key:videoParameter.keyName
                     contentType:@"text/plain" //@"video/mp4"
                      expression:expression
               completionHandler:completionHandler] continueWithBlock:^id(AWSTask *task) {
        if (task.error) {
            NSLog(@"Error: %@", task.error);
        }
        
        if (task.result) {
            AWSS3TransferUtilityUploadTask *uploadTask = task.result;
            // Do something with uploadTask.
            NSLog(@"Upload Starting!");
        }
        return nil;
    }];

S3下載

這裏先放着,下面進行補充

問題新增:(2019-06-06)

在連續上傳時,遇到了新的問題:APP啓動後第一次上傳很順利,然後,第二次再上傳時就出現問題。S3的沒有調用進度回調和完成回調。

[AWSS3TransferUtility registerS3TransferUtilityWithConfiguration:configuration forKey:@"LoftyApp"];

這裏的這個key,是寫死的,每次上傳調用的都是同一個AWSS3TransferUtility實例,由於這個原因(真實原因不明),造成了新的問題

解決辦法:

每次上傳的key都不一樣


//註冊
    [AWSS3TransferUtility registerS3TransferUtilityWithConfiguration:configuration forKey:[NSString stringWithFormat:@"LoftyApp_%@",videoParameter.keyName]];

//獲取AWSS3TransferUtility實例
    AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility S3TransferUtilityForKey:[NSString stringWithFormat:@"LoftyApp_%@",videoParameter.keyName]];

 

 

參考文獻:

https://www.jianshu.com/p/0a077f25891e

https://blog.csdn.net/label_A/article/details/80968939

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章