你的位置:首页 > 操作系统

[操作系统]iOS使用阿里云OSS对象存储 (SDK 2.1.1)


  最近项目中用到了阿里云OSS对象存储,用来存储APP中图片、音频等一些数据。但坑爹的阿里云居然在11月20日将SDK版本更新到了2.1.1,然而网上给出的教程都是1.*版本的(针对iOS),两个版本所调用的方法差别较大(自我感觉),当然原理都一样。所以看了两天SDK,自己封装了几个常用的方法。

一、OSS简单介绍

  OSS是提供非结构化数据存取的服务,非结构化数据一般包括图片、文档、音频、视频等一些文件。OSS提供了接口,开发者可以通过这些接口对数据进行上传或下载等操作。

  开通OSS服务后,创建一个bucket(数据容器,可以创建多个bucket,但是每个bucket名字唯一),在bucket属性里面可以设置bucket读写属性。然后所有的object(文件)都存储在bucket里面。

  bucket:

               bucket

  bucket控制台:

                

二、OSS SDK1.0与SDK2.0方法调用区别

  (1)SDK1.0方法调用形式

    在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>"];    //填入你的secretKey12     return [NSString stringWithFormat:@"OSS %@:%@", @"<accessKey>", signature];   //填入你的accessKey13   }];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];的方法,进行文件操作,具体代码下面给出。

三、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>"];    //明文设置client4   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

四、自己封装的上传、下载、拼接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     //初始化client40     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     //执行请求,获取请求结果task49     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.code70       }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就能够熟练使用这些方法。此文如果对大家有帮助,我很欣慰;如无帮助,敬请见谅。如有错误或者问题,可以指出或者问我。

 




深圳去希腊旅游报价办理希腊旅游签证跟团希腊旅游需要多少钱几月份去希腊旅游最好什么时候去希腊旅游最便宜深圳青青世界好不好玩? 深圳红树林那边可以踩单车吗?红树林租单车贵吗? 深圳青青世界游玩需要知道什么? 深圳怎么去河源龙源温泉? 武功山在哪里?武功山好玩吗? 稻城亚丁什么时候去最美? 澳门旅游观光塔有什么好玩的? 北京石景山游乐园摩天轮现在还在用吗? 春节三亚旅游哪里最好玩?2015年春节三亚旅游攻略推荐 北京什么时候有庙会?一般是什么时候开始? 鼓浪屿的小吃比较著名的有什么?大家都会去吃的是什么? 春节海南游,怎样比较省钱的? 台山到那琴半岛地质海洋公园开车有多远?台山到那琴半岛地质海洋公园怎么走? 那琴半岛地质海洋公园美食攻略?台山海洋公园有哪些好吃的? 那琴半岛地质海洋公园海鲜多少钱?台山海洋公园烧烤怎么收费? 那琴半岛地质海洋公园两日游多少钱?台山海洋公园吃饭方便吗? ADC084S021CIMMX/NOPB Datasheet ADC084S021CIMMX/NOPB Datasheet ADC084S051CIMMX/NOPB Datasheet ADC084S051CIMMX/NOPB Datasheet ADC084S101CIMMX/NOPB Datasheet ADC084S101CIMMX/NOPB Datasheet 去土耳其旅游多少钱 去土耳其旅游多少钱 去土耳其旅游多少钱 长江图片 长江图片 长江图片 西岛门票 西岛门票 西岛门票