最近項目中用到了阿里雲OSS對象存儲,用來存儲APP中圖片、音頻等一些數據。但坑爹的阿里雲竟然在11月20日將SDK版本更新到了2.1.1,然而網上給出的教程都是1.*版本的(針對iOS),兩個版本所調用的方法差異較大(自我感受),固然原理都同樣。因此看了兩天SDK,本身封裝了幾個經常使用的方法。html
1、OSS簡單介紹ios
OSS是提供非結構化數據存取的服務,非結構化數據通常包括圖片、文檔、音頻、視頻等一些文件。OSS提供了接口,開發者能夠經過這些接口對數據進行上傳或下載等操做。api
開通OSS服務後,建立一個bucket(數據容器,能夠建立多個bucket,可是每一個bucket名字惟一),在bucket屬性裏面能夠設置bucket讀寫屬性。而後全部的object(文件)都存儲在bucket裏面。緩存
bucket:dom
bucket控制檯:異步
2、OSS SDK1.0與SDK2.0方法調用區別async
(1)SDK1.0方法調用形式ide
在SDK1.0中,主要經過OSSService-Bucket方式進行操做。首先獲取service,設置service的數據中心域名和加簽等。而後建立bucket,設置bucket屬性。經過service調用一系列方法,並把bucket傳入方法中,獲取返回結果。實例代碼:函數
1 - (void)upLoadObjectWithKey:(NSString *)key object:(NSData *)object type:(NSString *)type{ 2 OSSData *ossData; //存取請求結果 3 id<ALBBOSSServiceProtocol> ossService = [ALBBOSSServiceProvider getService]; //獲取service 4 [ossService setGlobalDefaultBucketAcl:PRIVATE]; //訪問屬性爲私有 5 [ossService setGlobalDefaultBucketHostId:@"<yourHostId>"]; //設置你的域名 6 7 //加簽 8 [ossService setGenerateToken:^(NSString *method, NSString *md5, NSString *type, NSString *date, NSString *xoss, NSString *resource){ 9 10 NSString *content = [NSString stringWithFormat:@"%@\n%@\n%@\n%@\n%@%@", method, md5, type, date, xoss, resource]; 11 NSString *signature = [OSSTool calBase64Sha1WithData:content withKey:@"<secretKey>"]; //填入你的secretKey 12 return [NSString stringWithFormat:@"OSS %@:%@", @"<accessKey>", signature]; //填入你的accessKey 13 }]; 14 15 ossData = [ossService getOSSDataWithBucket:[ossService getBucket:@"yourBucketName"] key:key]; 16 [ossData setData:uploadData withType:type]; //設置上傳文件類型 17 [ossData enableUploadCheckMd5sum:YES]; 18 }
(2)SDK2.0方法調用形式工具
在SDK2.0中,主要以Client-(put/get..)Object方式進行操做。首先對client進行初始化。而後建立putObject/getObject對象,設置對象屬性,而後使用相似OSSTask *task = [client putObject:put];的方法,進行文件操做,具體代碼下面給出。
3、OSS簡單上傳文件操做
在使用OSS以前,須要引入OSS iOS SDK framework。在Xcode中,直接把framework拖入您對應的Target下便可,在彈出框勾選「Copy items if needed」
。若是項目依賴Pod,無需引入framework,只須要在Podfile文件中添加依賴"pod 'AliyunOSSiOS'"便可。而後在工程的頭文件中引入 #import <AliyunOSSiOS/OSSService.h>
(1)簡單設置client
OSSClient是OSS服務的iOS客戶端,它爲調用者提供了一系列的方法,能夠用來操做,管理存儲空間(bucket)和文件(object)等。示例代碼:
1 OSSClient *client; 2 NSString *endpoint = @"<hostId>"; //注意在控制檯獲取域名以後,要在前面加上http://,並去掉bucketName字段。例如從控制檯獲取域名爲「<bucketName>.oss-cn-beijing.aliyuncs.com」,則hostId應爲「http://oss-cn-beijing.aliyuncs.com」 3 id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:@"<your accessKeyId>" secretKey:@"<your accessKeySecret>"]; //明文設置client 4 client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential]; //初始化client
(2)文件上傳操做
上傳Object能夠直接上傳OSSData,或者經過NSURL上傳一個文件。經過使用OSSPutObjectRequest類進行上傳。示例代碼:
OSSPutObjectRequest * put = [OSSPutObjectRequest new]; // 必填字段 put.bucketName = @"<bucketName>"; put.objectKey = @"<objectKey>"; put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"]; // put.uploadingData = <NSData *>; // 直接上傳NSData // 可選字段,可不設置 put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // 當前上傳段長度、當前已經上傳總長度、一共須要上傳的總長度 NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend); }; // 如下可選字段的含義參考: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject // put.contentType = @""; // put.contentMd5 = @""; // put.contentEncoding = @""; // put.contentDisposition = @""; // put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // 能夠在上傳時設置元信息或者其餘HTTP頭部 OSSTask * putTask = [client putObject:put]; //client爲上一段初始化的client [putTask continueWithBlock:^id(OSSTask *task) { if (!task.error) { NSLog(@"upload object success!"); } else { NSLog(@"upload object failed, error: %@" , task.error); } return nil; }];
更多見官方iOS SDK
4、本身封裝的上傳、下載、拼接URL方法。
頭文件:
@interface AliyunAPIUtil : NSObject //獲取圖片URL + (NSString *) imageURLWithKey:(NSString *)key isPublic:(BOOL)isPublic; + (NSString *) imageURLWithKey:(NSString *)key isPublic:(BOOL)isPublic orginal:(BOOL)orginal; //上傳方法 - (id)initUploadWithCategory:(NSString *)category public:(BOOL)isPublic type:(NSString *)type data:(NSData *)uploadData; //上傳方法回調 - (void)startUploadWithCallback:(void (^)(BOOL success))uploadCallback; //下載方法 - (id)initDownLoadWithKey:(NSString *)key public:(BOOL)isPublic; //下載方法回調 - (void)startDownloadWithCallback:(void (^)(BOOL success))downloadCallback; @end
(1)上傳方法
1 /* 2 *上傳對象方法 3 */ 4 -(id)initUploadWithCategory:(NSString *)category public:(BOOL)isPublic type:(NSString *)type data:(NSData *)uploadData{ 5 self = [super init]; 6 7 //CDDoctorEntity *doctor = [[CDUser userDefaults] currentUser]; 8 long long int timevalue = (long long int)([NSDate date].timeIntervalSince1970 * 1000); 9 NSString *ID = @"102"; //測試用,自定義ID變量,標識上傳文件。 10 NSString *endpoint = @"<hostId>"; //域名 11 NSString *accessKey = @"<accessKey>"; 12 NSString *secretKey = @"<secretKey>"; 13 NSString *key = [NSString stringWithFormat:@"%@-ios-%@-%lld.%@",category, ID, timevalue, type]; //本身拼接key,用於標識對象。 14 15 id<OSSCredentialProvider> credential; 16 OSSClient *client; 17 OSSPutObjectRequest *put; 18 19 if(self){ //公有訪問 20 if(isPublic){ 21 credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:@"<accessKey>" secretKey:@"<accessKeySecret>"]; 22 } 23 else{ //私有訪問 24 25 //自定義加簽 26 credential = [[OSSCustomSignerCredentialProvider alloc] initWithImplementedSigner:^NSString *(NSString *contentToSign, NSError *__autoreleasing *error) { 27 28 NSString *signature = [OSSUtil calBase64Sha1WithData:contentToSign withSecret:secretKey]; // 這裏是用SDK內的工具函數進行本地加簽,建議您經過業務server實現遠程加簽 29 if (signature != nil) { 30 *error = nil; 31 } else { 32 //*error = [NSError errorWithDomain:@"<your domain>" code:-1001 userInfo:@"<your error info>"]; 33 return nil; 34 } 35 return [NSString stringWithFormat:@"OSS %@:%@", accessKey, signature]; 36 }]; 37 } 38 39 //初始化client 40 client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential]; 41 42 //初始化put請求體並設定請求對象屬性 43 put = [OSSPutObjectRequest new]; 44 put.bucketName = @"<bucketName>"; 45 put.objectKey = key; 46 put.uploadingData = uploadData; 47 48 //執行請求,獲取請求結果task 49 self.task = [client putObject:put]; 50 } 51 return self; 52 } 53 54 /* 55 * 取得請求結果後的回調方法。用於處理請求完畢後的操做。 56 */ 57 - (void)startUploadWithCallback:(void (^)(BOOL success))uploadCallback{ 58 59 //異步處理返回結果 60 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 61 62 [self.task continueWithBlock:^id(OSSTask *task) { 63 if (!task.error) { 64 NSLog(@"上傳成功"); 65 uploadCallback(YES); 66 } else { 67 NSLog(@"上傳失敗,錯誤提示: %@" , task.error); 68 uploadCallback(NO); 69 //task.error.code 70 } 71 return nil; 72 }]; 73 }); 74 }
方法調用:
AliyunAPIUtil *upload = [[AliyunAPIUtil alloc] initUploadWithCategory:@"avator-img" public:NO type:@"jpg" data:UIImageJPEGRepresentation(image, 0.5)]; //image爲上傳的圖片對象,本身定義。 [upload startUploadWithCallback:^(BOOL success) { if (success) { NSLog(@"上傳成功"); //其餘操做 }else{} }];
(2)下載方法
1 /* 2 *下載對象方法 3 */ 4 -(id)initDownLoadWithKey:(NSString *)key public:(BOOL)isPublic{ 5 self = [super init]; 6 if(self){ 7 self.fileKey = key; 8 self.isPublic = isPublic; 9 NSString *endpoint = @"<hostId>"; 10 NSString *accessKey = @"<accessKey>"; 11 NSString *secretKey = @"<secrerKey>"; 12 13 OSSClient *client; 14 OSSGetObjectRequest *get; 15 id<OSSCredentialProvider> credential; 16 17 if(self.isPublic){ //公有方式訪問19 credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:@"<your accessKeyId>" secretKey:@"<your accessKeySecret>"]; 20 } 21 else{ //私有方式訪問 22 credential = [[OSSCustomSignerCredentialProvider alloc] initWithImplementedSigner:^NSString *(NSString *contentToSign, NSError *__autoreleasing *error) { 23 24 NSString *signature = [OSSUtil calBase64Sha1WithData:contentToSign withSecret:secretKey]; // 這裏是用SDK內的工具函數進行本地加簽,建議您經過業務server實現遠程加簽 25 26 if (signature != nil) { 27 *error = nil; 28 } else { 29 //*error = [NSError errorWithDomain:@"<your domain>" code:-1001 userInfo:@"<your error info>"]; 30 return nil; 31 } 32 return [NSString stringWithFormat:@"OSS %@:%@", accessKey, signature]; 33 }]; 34 } 35 36 //初試化client客戶端 37 client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential]; 38 39 //初始化get請求對象,並設定get的屬性值 40 get = [OSSGetObjectRequest new]; 41 get.bucketName = @"<bucketName>"; 42 get.objectKey = key; 43 self.task = [client getObject:get]; 44 } 45 return self; 46 } 47 48 /* 49 * 取得請求結果後的回調方法。用於處理請求完畢後的操做。 50 */ 51 -(void)startDownloadWithCallback:(void (^)(BOOL success))downloadCallback{ 52 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 53 54 [self.task continueWithSuccessBlock:^id(OSSTask *task) { 55 if(!task.error){ 56 downloadCallback(YES); 57 } 58 else{ 59 downloadCallback(NO); 60 } 61 return nil; 62 }]; 63 }); 64 }
(3)本身加簽,拼接URL
若是想經過其餘方式訪問存儲在雲端的Object。例如在緩存APP頭像到雲端後,想經過使用SDWebImage獲取頭像,這時候就須要知道object的URL。當bucket設置爲私有讀寫時,須要加簽生成URL。
+(NSString *)imageURLWithKey:(NSString *)key isPublic:(BOOL)isPublic{ //key參數在上傳文件時候生成的,保存在本地,獲取文件時經過key去索引 if(isPublic){ //公有訪問URL return [NSString stringWithFormat:@"http://<bucketName>.<hostId>/%@",key]; } else{ //私有訪問URL long long int timevalue = (long long int)([NSDate date].timeIntervalSince1970 +60); //設置URL超時時間,當前設置爲60秒有效時間 /* *加簽其實是一個核對機制。在這裏通常將timevalue、bucketname、key、secretKey進行加密並與域名等字段鏈接,生成URL。而後服務端解析 *這些字段進行覈對,覈對成功則返回正確數據。在生成signature時,以上字段必須添加,還有一些其餘屬性能夠不添加。 */ NSString *string = [NSString stringWithFormat:@"GET\n\n\n%lld\n/<bucketName>/%@",timevalue,key]; //不要忘記設定bucketName NSLog(@"%@",string); NSString *signature = [OSSUtil calBase64Sha1WithData:string withSecret:@"<secretKey>"]; NSString *encodedSignature = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)signature, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8)); NSString *urlString = [NSString stringWithFormat:@"http://<bucketName>.<hostId>/%@?Expires=%lld&OSSAccessKeyId=<accessKey>&Signature=%@",key,timevalue,encodedSignature]; //以<>代表的爲未傳出參數,須要本身修改。 return urlString; } }
signature相關解釋:
(1)http://help.aliyun.com/document_detail/oss/api-reference/access-control/signature-url.html?spm=5176.7618386.5.1.U9vNfL
(2)http://help.aliyun.com/document_detail/oss/api-reference/access-control/signature-header.html
以上的一些方法,在阿里雲的SDK中,大部分已經給出。各位可能只看看SDK就可以熟練使用這些方法。此文若是對你們有幫助,我很欣慰;如無幫助,敬請見諒。若有錯誤或者問題,能夠指出或者問我。