iOS使用阿里雲OSS對象存儲 (SDK 2.1.1)

  最近項目中用到了阿里雲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

  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就可以熟練使用這些方法。此文若是對你們有幫助,我很欣慰;如無幫助,敬請見諒。若有錯誤或者問題,能夠指出或者問我。

相關文章
相關標籤/搜索