iOS - 阿里云OSS云存储
前言
最近在做项目时,后台的人说修改个人资料时头像要通过OSS上传。我当时就懵逼了,这是咋回事,是一种协议吗?一查才知道不是,但除了阿里的官方文档,也查不到太多的资料。于是只能一步一步探索,并且记录下来希望能有点j用。
- OSS是什么,有什么好处。
简单点说,OSS就是把数据放到阿里的服务器(以下简称为云服)里存储的服务。
好处:
- 成本低
其收费规则:
阿里云定价文档
对象存储OSS仅按照您的实际使用容量收费,您无需预先购买存储和流量容量,随着您业务的发展,您将享受到更多的基础设施成本优势。
好处显而易见,收费低,减轻了我们后台服务器(以下简称为后服)的压力。
- 数据安全,多重备份。
- 数据处理服务。图片处理、音视频转码、内容加速分发、鉴黄服务、归档服务等。
- 数据自动管理生命周期等。
- OSS流程原理
不用OSS时,如果我们要上传照片到后服,只需要发起一个请求。
// 1.处理图片
// 2.上传到后服
采用OSS后,需要发起两个请求。
// 1.处理图片
// 2.上传到云服,成功后拼接图片路径url
// 3.后服接口中图片参数应为NSString,把第2步拼接的url作为参数上传到后服
使用OSS
- 准备工作
开通OSS并配置云服,这种事通常都是由后台的人管的吧。
所以问后台的人,拿到AccessKey
和SecretKey
。还有Bucket
(存储空间,相当于主目录),内、外网用的Endpoint
(访问域名)。
内、外网区别在于:内网是用于同一Bucket阿里云产品之间,例如把图片拿去分析之类的操作。外网就是我们把图片上传到云服以及不同Bucket之类的操作。本文探究的是外网上传图片操作。
image- 上传照片
直接上代码
@interface FHProfileInfoViewModel()
@property (nonatomic, strong) OSSClient *client;
@end
@implementation FHProfileInfoViewModel
- (void)aliyunWithFileName:(NSString *)fileName {
[MBProgressHUD fh_showMessage:@"正在修改"];
OSSPutObjectRequest * put = [OSSPutObjectRequest new];
put.bucketName = @"你项目的bucketName,相当于主目录";
// objectKey为云服储存的文件名
put.objectKey = fileName;
UIImage *testImage = [UIImage imageNamed:@"test"];
NSData *testData = UIImageJPEGRepresentation(testImage, 0.1);
put.uploadingData = testData;
// 此处可查看上传进度
// put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
// NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
// };
OSSTask * putTask = [self.client putObject:put];
[putTask continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
NSLog(@"upload object success!");
[MBProgressHUD fh_hideHUD];
// 1.拼接url
// 2.调用后台接口
} else {
NSLog(@"upload object failed, error: %@" , task.error);
[MBProgressHUD fh_hideHUD];
[MBProgressHUD fh_showError:@"修改失败"];
}
return nil;
}];
// 可以等待任务完成
[putTask waitUntilFinished];
}
- (OSSClient *)client {
if (!_client) {
NSString *endpoint = @"你项目的endpoint";
NSString *accessKeyid = @"你项目的accessKeyid";
NSString *secretKeyId = @"你项目的secretKeyId";
NSString *securityToken = @"";// 可空 看后台
id<OSSCredentialProvider> credential = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:accessKeyid secretKeyId:secretKeyId securityToken:securityToken];
_client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential];
}
return _client;
}
@end
1⃣️官方文档建议OSSClient
全局一个,注意配置好相应数据。
2⃣️objectKey为文件名。
3⃣[putTask waitUntilFinished];
类似GCD栏杆函数。这里因为要等上传成功后拼接url,再上传到后台,所以调用。
4⃣️最后来说说上传成功后的url拼接。
刚开始测的时候,发现上传成功的回调里,并未找到。上网搜也搜不到教程。后来听了大佬说才知道原来是这样。
NSString *picUrlStr = [NSString stringWithFormat:@"http://%@.%@/%@", bucketName, endpoint, objectName];
// 即"http://" + bucketName + "." + this.endpoint + "/" + objectName;
再说说一些特别点
-
OSS服务里,不存在文件夹这种概念。但是我们命名
objectName
时,可以带上/
(不能以"/"或""开头),看上去就像文件夹管理一样。 -
如果传了相同
objectName
的文件,将会覆盖。 -
图片文件名如果没有没有加上.png,那么在浏览器里打开时会直接下载。如果加了,会展示出来。
亲测,- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder
,这个方法未加.png也能成功显示。
所以名字见仁见智吧。如果有需要就和后台、安卓的人商量好命名规则。