寫在開頭
最近工程中做了一個視頻上傳的相關需求,使用了亞馬遜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