最近要用到阿里云的OSS上传,主要原因是需要跨境访问服务器,关于OSS 存储的好处,大家可以自行百度。
1、 打开调试日志 [OSSLog enableLog];
2、初始化
方式一:
id<OSSCredentialProvider> credential = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:@"" secretKeyId:@"" securityToken:@""];
这里面的参数是我们自己的server 调用阿里云api 得到的并返回给我们,每次都不一样的,不要认为是阿里给定的appkey 和appsecret
方式二:
__weak typeof(self)weakSelf = self;
id<OSSCredentialProvider> credential2 = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * {
NSURL * url = [NSURL URLWithString:creditialUrl];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
OSSTaskCompletionSource * tcs = [OSSTaskCompletionSource taskCompletionSource];
NSURLSession * session = [NSURLSession sharedSession];
NSURLSessionTask * sessionTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
[tcs setError:error];
return;
}
[tcs setResult:data];
}];
[sessionTask resume];
[tcs.task waitUntilFinished];
if (tcs.task.error) {
NSLog(@"get token error: %@", tcs.task.error);
return nil;
} else {
NSDictionary * object = [NSJSONSerialization JSONObjectWithData:tcs.task.result
options:kNilOptions
error:nil];
NSDictionary * dataDic = object[@"data"];
NSDictionary * cridentDic = dataDic[@"Credentials"];
OSSFederationToken * token = [OSSFederationToken new];
token.tAccessKey = [cridentDic objectForKey:@"AccessKeyId"];
token.tSecretKey = [cridentDic objectForKey:@"AccessKeySecret"];
token.tToken = [cridentDic objectForKey:@"SecurityToken"];
token.expirationTimeInGMTFormat = [cridentDic objectForKey:@"Expiration"];
weakSelf.buckName = dataDic[@"BucketName"];
weakSelf.objectKey = dataDic[@"ObjectKey"];
// weakSelf.endPoint = dataDic[@"Endpoint"];
NSLog(@"get token: %@", token);
return token;
}
}];
通过该方法直接通过给定的地址 向我们server调用,并赋值给相关参数
以上是通过STS的方法,比较推荐的一种,也可以使用自签名,我没使用,这里不再累述
3、配置方法
OSSClientConfiguration * conf = [OSSClientConfiguration new];
// 最大重试次数
conf.maxRetryCount = 2;
//最大并发请求数
conf.maxConcurrentRequestCount = 2;
//请求超时时间
conf.timeoutIntervalForRequest = 30;
// 单个Object下载的最长持续时间
conf.timeoutIntervalForResource = 24 * 60 * 60;
client = [[OSSClient alloc] initWithEndpoint:endPoint credentialProvider:credential clientConfiguration:conf];
4、上传,包括同步上传和异步上传 (如果需要下载,前面配置都一样,下面的不一样)
异步上传
- (void)uploadObjectAsync {
OSSPutObjectRequest * put = [OSSPutObjectRequest new];
// required fields
put.bucketName = @"contestia-us-west-bucket1";
put.objectKey = @"test1/test3.mp4";
// NSString * docDir = [self getDocumentDirectory];
// put.uploadingFileURL = [NSURL fileURLWithPath:[docDir stringByAppendingPathComponent:@"2"]];
NSString * filePath = [[NSBundle mainBundle] pathForResource:@"test3" ofType:@"mp4"];
NSLog(@"filePath-->%@",filePath);
put.uploadingFileURL = [NSURL fileURLWithPath:filePath];
// optional fields
put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};
put.contentType = @"video/mp4"; //一定要设置,不然会默认“application/mp4”
put.contentMd5 = @"";
put.contentEncoding = @"";
put.contentDisposition = @"";
OSSTask * putTask = [client putObject:put];
[putTask continueWithBlock:^id(OSSTask *task) {
NSLog(@"objectKey: %@", put.objectKey);
if (!task.error) {
NSLog(@"upload object success!");
} else {
NSLog(@"upload object failed, error: %@,%@" , task.error,task.result);
}
return nil;
}];
}
同步和异步的代码区别就是在putTask 后面去阻塞线程 [putTask waitUntilFinished]; // 阻塞直到上传完成
下载和上传方法类似 只是请求的类不一样 OSSGetObjectRequest也可以断点续传
5、主要问题
权限过期 xx expired 服务端设置过期时间太短,你的鉴权过去了,重新访问
ErrorCode: AccessDenied 无权限,这个问题遇到的比较多,但是引起这个问题的有好多情况,大部分是因为控制台配置权限没有打开,可以登录阿里的控制台去对象存储OSS 内查看设置相关权限,
可以参考以下链接 https://help.aliyun.com/document_detail/42775.html?spm=5176.doc31935.6.1062.AGIOtB
https://help.aliyun.com/document_detail/31945.html?spm=5176.doc42775.6.1060.qOHKnF
也可以在里面搜索关键词,按照步骤还是可以解决的
当你们发现这些都没问题了,检查下我们自己吧,或者服务端,我们搞了好久发现后台sdk下载错了,一把辛酸泪啊