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控制台:
二、OSS SDK1.0与SDK2.0方法调用区别
(1)SDK1.0方法调用形式
在SDK1.0中,主要通过OSSService-Bucket方式进行操作。首先获取service,设置service的数据中心域名和加签等。然后创建bucket,设置bucket属性。通过service调用一系列方法,并把bucket传入方法中,获取返回结果。实例代码:
- (void)upLoadObjectWithKey:(NSString *)key object:(NSData *)object type:(NSString *)type{
OSSData *ossData; //存取请求结果
id<ALBBOSSServiceProtocol> ossService = [ALBBOSSServiceProvider getService]; //获取service
[ossService setGlobalDefaultBucketAcl:PRIVATE]; //访问属性为私有
[ossService setGlobalDefaultBucketHostId:@"<yourHostId>"]; //设置你的域名
//加签
[ossService setGenerateToken:^(NSString *method, NSString *md5, NSString *type, NSString *date, NSString *xoss, NSString *resource){
NSString *content = [NSString stringWithFormat:@"%@\n%@\n%@\n%@\n%@%@", method, md5, type, date, xoss, resource];
NSString *signature = [OSSTool calBase64Sha1WithData:content withKey:@"<secretKey>"]; //填入你的secretKey
return [NSString stringWithFormat:@"OSS %@:%@", @"<accessKey>", signature]; //填入你的accessKey
}];
ossData = [ossService getOSSDataWithBucket:[ossService getBucket:@"yourBucketName"] key:key];
[ossData setData:uploadData withType:type]; //设置上传文件类型
[ossData enableUploadCheckMd5sum:YES];
}
(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)等。示例代码:
OSSClient *client;
NSString *endpoint = @"<hostId>"; //注意在控制台获取域名之后,要在前面加上http://,并去掉bucketName字段。例如从控制台获取域名为“<bucketName>.oss-cn-beijing.aliyuncs.com”,则hostId应为“http://oss-cn-beijing.aliyuncs.com”
id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:@"<your accessKeyId>" secretKey:@"<your accessKeySecret>"]; //明文设置client
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)上传方法
/*
*上传对象方法
*/
-(id)initUploadWithCategory:(NSString *)category public:(BOOL)isPublic type:(NSString *)type data:(NSData *)uploadData{
self = [super init]; //CDDoctorEntity *doctor = [[CDUser userDefaults] currentUser];
long long int timevalue = (long long int)([NSDate date].timeIntervalSince1970 * );
NSString *ID = @""; //测试用,自定义ID变量,标识上传文件。
NSString *endpoint = @"<hostId>"; //域名
NSString *accessKey = @"<accessKey>";
NSString *secretKey = @"<secretKey>";
NSString *key = [NSString stringWithFormat:@"%@-ios-%@-%lld.%@",category, ID, timevalue, type]; //自己拼接key,用于标识对象。 id<OSSCredentialProvider> credential;
OSSClient *client;
OSSPutObjectRequest *put; if(self){ //公有访问
if(isPublic){
credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:@"<accessKey>" secretKey:@"<accessKeySecret>"];
}
else{ //私有访问 //自定义加签
credential = [[OSSCustomSignerCredentialProvider alloc] initWithImplementedSigner:^NSString *(NSString *contentToSign, NSError *__autoreleasing *error) { NSString *signature = [OSSUtil calBase64Sha1WithData:contentToSign withSecret:secretKey]; // 这里是用SDK内的工具函数进行本地加签,建议您通过业务server实现远程加签
if (signature != nil) {
*error = nil;
} else {
//*error = [NSError errorWithDomain:@"<your domain>" code:-1001 userInfo:@"<your error info>"];
return nil;
}
return [NSString stringWithFormat:@"OSS %@:%@", accessKey, signature];
}];
} //初始化client
client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential]; //初始化put请求体并设定请求对象属性
put = [OSSPutObjectRequest new];
put.bucketName = @"<bucketName>";
put.objectKey = key;
put.uploadingData = uploadData; //执行请求,获取请求结果task
self.task = [client putObject:put];
}
return self;
} /*
* 取得请求结果后的回调方法。用于处理请求完毕后的操作。
*/
- (void)startUploadWithCallback:(void (^)(BOOL success))uploadCallback{ //异步处理返回结果
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{ [self.task continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
NSLog(@"上传成功");
uploadCallback(YES);
} else {
NSLog(@"上传失败,错误提示: %@" , task.error);
uploadCallback(NO);
//task.error.code
}
return nil;
}];
});
}
方法调用:
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)下载方法
/*
*下载对象方法
*/
-(id)initDownLoadWithKey:(NSString *)key public:(BOOL)isPublic{
self = [super init];
if(self){
self.fileKey = key;
self.isPublic = isPublic;
NSString *endpoint = @"<hostId>";
NSString *accessKey = @"<accessKey>";
NSString *secretKey = @"<secrerKey>"; OSSClient *client;
OSSGetObjectRequest *get;
id<OSSCredentialProvider> credential; if(self.isPublic){ //公有方式访问 credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:@"<your accessKeyId>" secretKey:@"<your accessKeySecret>"];
}
else{ //私有方式访问
credential = [[OSSCustomSignerCredentialProvider alloc] initWithImplementedSigner:^NSString *(NSString *contentToSign, NSError *__autoreleasing *error) { NSString *signature = [OSSUtil calBase64Sha1WithData:contentToSign withSecret:secretKey]; // 这里是用SDK内的工具函数进行本地加签,建议您通过业务server实现远程加签 if (signature != nil) {
*error = nil;
} else {
//*error = [NSError errorWithDomain:@"<your domain>" code:-1001 userInfo:@"<your error info>"];
return nil;
}
return [NSString stringWithFormat:@"OSS %@:%@", accessKey, signature];
}];
} //初试化client客户端
client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential]; //初始化get请求对象,并设定get的属性值
get = [OSSGetObjectRequest new];
get.bucketName = @"<bucketName>";
get.objectKey = key;
self.task = [client getObject:get];
}
return self;
} /*
* 取得请求结果后的回调方法。用于处理请求完毕后的操作。
*/
-(void)startDownloadWithCallback:(void (^)(BOOL success))downloadCallback{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{ [self.task continueWithSuccessBlock:^id(OSSTask *task) {
if(!task.error){
downloadCallback(YES);
}
else{
downloadCallback(NO);
}
return nil;
}];
});
}
(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 +); //设置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就能够熟练使用这些方法。此文如果对大家有帮助,我很欣慰;如无帮助,敬请见谅。如有错误或者问题,可以指出或者问我。
iOS使用阿里云OSS对象存储 (SDK 2.1.1)的更多相关文章
- Java使用阿里云OSS对象存储上传图片
原 Java使用阿里云OSS对象存储上传图片 2017年03月27日 10:47:28 陌上桑花开花 阅读数 26804更多 分类专栏: 工作案例总结 版权声明:本文为博主原创文章,遵循CC 4.0 ...
- SpringBoot整合阿里云OSS对象存储实现文件上传
1. 准备工作: 一.首先登录阿里云OSS对象存储控制台创建一个Bucket作为你的存储空间. 二.创建Access Keyan按要求创建进行,这里的方法步骤我就不展现出来了,你们可以自行查询阿里云文 ...
- 阿里云Oss对象存储
将文件保存到阿里云上. 1.添加对象存储OSS空间 (新建Bucket) 可以在阿里云后台对象存储里面添加,也可以通过api添加.添加之后设置权限. skd使用. 1安装 Aliyun.OSS.SDK ...
- C# .net Ueditor实现图片上传到阿里云OSS 对象存储
在学习的时候,项目中需要实现在Ueditor编辑器中将图片上传到云储存中,老师演示的是上传到又拍云存储,既然看了一遍,直接照搬不算本事,咱们可以依葫芦画瓢自己来动手玩玩其它的云存储服务. 现在云计算产 ...
- PHP 上传文件至阿里云OSS对象存储
简述 1.阿里云开通对象存储服务 OSS 并创建Bucket 2.下载PHP SDK至框架扩展目录,点我下载 3.码上code 阿里云操作 开通对象存储服务 OSS 创建 Bucket 配置Acces ...
- 阿里云OSS对象存储 简单上传文件
不得不说阿里云的命名比较让人摸不着头脑,开始以为是文件存储NAS,弄了半天什么文件系统,挂载点的搞不明白.后来才搞清楚原来 对象存储OSS才是我需要的. 其中EndPoint就是画红框的部分,但是要加 ...
- 阿里云OSS对象存储服务(二)
一.使用SDK 在OSS的概览页右下角找到"Bucket管理",点击"OSS学习路径" 点击"Java SDK"进入SDK开发文档 二.创建 ...
- 阿里云OSS对象存储服务(一)
一.开通"对象存储OSS"服务 申请阿里云账号 实名认证 开通"对象存储OSS"服务 进入管理控制台 二.控制台使用 1.创建Bucket 命名:guli-fi ...
- 阿里云oss对象存储配置CDN
阿里云oss对象存储配置CDN 1.打开阿里云CDN 2.填写信息,这个地方要注意,我的备案域名是www.ljwXXX.work,我们可以自定义一个域名,test.ljwXXX.work作为加速域名. ...
随机推荐
- Django 1.6 的测试驱动开发
http://www.oschina.net/translate/django-1-6-test-driven-development 测试驱动开发(TDD)是一个迭代的开发周期,强调编写实际代码之前 ...
- bit、sbin、sfr、sfr16 区别分析
1.bit 和 sbit 都是 C51 扩展的变量类型. bit 和 int char 之类的差不多,只不过 char=8 位, bit=1 位而已.都是变量,编译器在编译过程中分配地址.除非你指定, ...
- Altium Designer 从导入DXF文件,并转换成板框
大多数人都知道,PADS中导入DXF文件,然后转换成板框,是很方便的.AD也同样可以做到. PADS导入DXF见:http://www.cnblogs.com/craftor/archive/2012 ...
- 在 C++Builder 工程里使用 Visual C++ DLL(3个工具) good
译者序: 第一次读这篇文章是在 2001 年 10 月,帮我解决了一点小问题.本来不好意思翻译,因为英语水平实在太差.最近发现不少网友在问在 C++Builder 的工程里调用 Visual C++ ...
- Struts2再爆远程代码执行漏洞
Struts又爆远程代码执行漏洞!在这次的漏洞中,攻击者可以通过操纵参数远程执行恶意代码.Struts 2.3.15.1之前的版本,参数action的值redirect以及redirectAction ...
- 怎么添加项目到SVN上面
一.通过SVN客户端向服务器上面添加项目 1.在服务器上面创建一个文件夹,文件夹以项目名称命名. 2.在合适目录下右击后,点击SVN Checkout,将你在服务器上面创建的目录checkout下来 ...
- Count Complete Tree Nodes ——LeetCode
Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from W ...
- Codeforces Round #326 (Div. 1) - C. Duff in the Army 树上倍增算法
题意:一个n个点的数, m个人住在其中的某些点上, 每个人的标号1-m, 询问u-v 路径上标号前a个人,并输出标号,a < 10. 作法, 利用倍增, ID[j][i] 表示i到i的第2^j个 ...
- url找不到指定位置
刚才遇到了把css装入一个文件夹下,然后有的图片失效了. 后来解决是在.css里把./images 换成 ../images 原来css找图片的地址是基于自身.css文件的位置寻找的,不是以引用它的. ...
- Python字符串连接的5种方法
总结了一下Python字符串连接的5种方法: 加号 第一种,有编程经验的人,估计都知道很多语言里面是用加号连接两个字符串,Python里面也是如此直接用 "+" 来连接两个字符串: ...