美文网首页iOS 知识点iOS学霸笔记热门
2017 iOS 阿里云OSS上传音频,视频,多图,单图完整版

2017 iOS 阿里云OSS上传音频,视频,多图,单图完整版

作者: King_iOS | 来源:发表于2017-07-08 14:51 被阅读1056次
    实现功能:这里主要说OSS上传
    • 通常情况下移动端所展示的数据是从公司服务器(不是阿里云)请求得到的(下载)。
      所以这里所实现的功能是在iOS移动端上传数据到阿里云服务器(OSS上传)。
    • 从相册获取单图,多图,视频 以及录音,拍照,拍摄视频。

    跟几乎所有的在使用第三方SDK时一样,一般只需要按照官方文档的几个步骤就能实现SDK里的功能。

    OSS上传实现过程:分三步

    前提条件:

    • 导入阿里云SDK pod 'AliyunOSSiOS', '~> 2.6.0'
    • 导入SDK头文件 #import <AliyunOSSiOS/OSSService.h>
    1.第一步:初始化SDK (初始化SDK分3种:明文设置模式,STS鉴权模式,自签名模式)

    1.1 明文设置:这个是自己在测试中使用的。正式项目中一般采用另外两种模式。我们公司采用的是STS鉴权模式。
    表面上明文设置是要有ID和Secret。这个是在官网注册,一般是公司后台给你。其实不用设置就可以初始化。
    代码如下:

     id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:@"Access Key ID" secretKey:@"Access Key Secret"];
     client = [[OSSClient alloc] initWithEndpoint:endPoint credentialProvider:credential];
    

    1.2 STS鉴权模式:
    何为鉴权模式?
    请注意上面明文设置情况下是客户端直接与阿里云交互,只涉及到这两者。
    STS模式下有三者参与:客户端,公司服务器,阿里云服务器。
    交互流程:此时公司服务器作为中间者;
    具体请看官方解释:看不明白也不要紧🕷

    鉴权模式交互图鉴权模式交互图

    方案的详细描述如下:

    • App用户登录。App用户身份是客户自己管理。客户可以自定义身份管理系统,也可以使用外部Web账号或OpenID。对于每个有效的App用户来说,AppServer可以确切地定义出每个App用户的最小访问权限。
    • AppServer请求STS服务获取一个安全令牌(SecurityToken)。在调用STS之前,AppServer需要确定App用户的最小访问权限(用Policy语法描述)以及授权的过期时间。然后通过调用STS的AssumeRole(扮演角色)接口来获取安全令牌。角色管理与使用相关内容请参考RAM使用指南中的角色管理。
    • STS返回给AppServer一个有效的访问凭证,App端称为FederationToken,包括一个安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)以及过期时间。
    • AppServer将FederationToken返回给ClientApp。ClientApp可以缓存这个凭证。当凭证失效时,ClientApp需要向AppServer申请新的有效访问凭证。比如,访问凭证有效期为1小时,那么ClientApp可以每30分钟向AppServer请求更新访问凭证。
    • ClientApp使用本地缓存的FederationToken去请求Aliyun Service API。云服务会感知STS访问凭证,并会依赖STS服务来验证访问凭证,并正确响应用户请求。

    关于鉴权模式代码:
    阿里云给出的demo是用苹果原生API NSURLSession来实现的,我这里用的是AFN实现
    由于这种模式下需要有后台参与,后台会提供接口(参数请求体和URL),自己按照后台要求设置好了就行。

      //STS鉴权模式
      //设置请求体参数,这里的参数有两个,具体参数设置跟公司后台有关
       NSString *mobile = @“/////////”;
       NSString  *secretString = [NSString stringWithFormat:@"%@",mobile];
     
        //直接设置StsToken
        id<OSSCredentialProvider> credential2 = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * {
            OSSTaskCompletionSource * tcs = [OSSTaskCompletionSource taskCompletionSource];
            
             //后台给的url链接
            NSString *string = @"////////////////////////////////";
            NSDictionary *dict = @{@"mobile":mobile,@"sign":secretString};
            
            AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            
            //设置信任CA证书 在https传输情况下需要设置 不然会报错(如果CA证书是经过专业认证的,xcode里是不需要导入CA证书的,只需要设置以下几行代码就行)
            AFSecurityPolicy * policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
            policy.allowInvalidCertificates = YES;
            policy.validatesDomainName = NO;
            manager.securityPolicy = policy;
        
            manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
            [manager POST:string parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                NSLog(@"%@",responseObject);
                
            self.responseObject = responseObject;
            [tcs setResult:responseObject];
                
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                NSLog(@"%@",error);
                if (error) {
                    [tcs setError:error];
                    return;
                }
            }];
            
            //同步
            [tcs.task waitUntilFinished];
            
            if (tcs.task.error) {
                NSLog(@"get token error: %@", tcs.task.error);
                return nil;
            }
            else {
                //获取token返回的参数
                OSSFederationToken * token = [OSSFederationToken new];
                token.tAccessKey = [self.responseObject objectForKey:@"AccessKeyId"];
                token.tSecretKey = [self.responseObject objectForKey:@"AccessKeySecret"];
                token.tToken = [self.responseObject objectForKey:@"SecurityToken"];
                token.expirationTimeInGMTFormat = [self.responseObject objectForKey:@"Expiration"];
                NSLog(@"get token: %@", token);
                return token;
            }
            
        }];
        
        //网络配置
        OSSClientConfiguration * conf = [OSSClientConfiguration new];
        conf.maxRetryCount = 2;
        conf.timeoutIntervalForRequest = 30;
        conf.timeoutIntervalForResource = 24 * 60 * 60;
        
        client = [[OSSClient alloc] initWithEndpoint:endPoint credentialProvider:credential2 clientConfiguration:conf];
    

    1.3 自签名模式
    由于没有使用过这种模式,所以抱歉这里无从做说明。

    第二步:上传文件(初始化成功后就可以开始上传了)

    OSS支持两种文件格式上传,NSData和NSUrl。我这里是将所有文件转化成NSData然后再一一上传。

       //上传请求类
        OSSPutObjectRequest * request = [OSSPutObjectRequest new];
        //文件夹名 后台给出
        request.bucketName = @“//////////“;
        //objectKey为文件名 一般自己拼接
        request.objectKey = objectKey;
        //上传数据类型为NSData
        request.uploadingData = uploadData;
    
     OSSTask * putTask = [client putObject:request];
        [putTask continueWithBlock:^id(OSSTask *task) {
            if (!task.error) {
                //每次上传完一个文件都要回调
                NSLog(@"上传成功!");
            } else {
                //上传失败后回调一次
                NSLog(@"upload object failed, error: %@" , task.error);
                }
            return nil;
        }];
        
        //同步上传(去掉就是异步)因为我上传的文件有多种包括音视频,图片。而且OSS这边是每上传成功一个文件都要回调一次。比如我成功上传5张图片,那么就要回调5次。所以这个时候我就无法判断文件是否都上传完成。所以我就把这些上传的文件放在调度组里面,这样所有文件上传成功后我这边就知道了。如果上传放在调度组里,那么这里的同步上传就必须加上。
        [putTask waitUntilFinished];
        
        //上传进度
        request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
            NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
         };
    
    第三步:上传成功后设置回调链接(这一步不设置不影响上传,只是为了安全考虑在你上传成功后 后台需要有一个回调,所以才设置这个。一旦后台采用这种回调机制,那么你就必须得设置好回调,不然后台那边拿不到这个回调链接)
        //上传回调参数和URL(这里是后台给的接口)
        获取用户ID
        NSString *userId = @“//////////”;
        NSString *upUrl = @"////////////////////";
        
        //不同类型的数据设置不同的文件名 根据文件名可以设置不同类型的回调参数
        //头像
        if ([objectKey rangeOfString:@"anchorImage"].location != NSNotFound){
            //头像上传回调请求体 这里objectKey充当返回给后台URL的后缀
            NSString *callBackBody = [NSString stringWithFormat:@"imageUrl=%@&mimeType=headimage&userId=%@",objectKey,userId];
            // 设置回调参数
            request.callbackParam = @{
                                      @"callbackUrl":upUrl,
                                      @"callbackBody":callBackBody,
                                      @"callbackBodyType":@"application/json"
                                      };
        }
    

    所以完整简单而又安全的OSS上传就只有以上三步,初始化SDK采用STS鉴权模式,上传文件,上传成功后设置回调链接。

    刚开始做OSS上传的同学只需要简单两步就可以完成上传功能。
    1.明文设置(初始化SDK)
    2.上传 (具备条件,上传的文件是NSData或NSUrl,后台给bucketName即文件夹名)

    建议自己在阿里云花几块钱注册一个OSS账号来测试自己上传的文件是否成功到阿里云服务器。

    • 关于阿里云上传主要都在LCAliyunOSS里
    • 头像和视频上传在LCPickerController里
    • 多图相册上传使用的是第三方LPDQuoteImagesView
    • 音频上传使用的是第三方IQAudioRecorderController

    最后最重要最重要的看这里DEMO

    相关文章

      网友评论

      • 没打伞的鱼:感谢分享,看官方文档真是看的头痛,你写的简单好用
      • Big_Zheng:你好,OSS上传视频是可以的,但是能在线播放吗?在阿里云后台看到的视频是mp4格式,但是不能在线播放,不知道能不能在app上在线播放
      • 傲古飞雪::+1: :+1: 非常感谢,Demo写的很完整:手写布局,中文注释,Pod多库,美感图标。必须是千锤百炼。

        还待完善:上传取消,上传失败【用户进入后台】,应用服务器数据库更新数据。

        有1个问题请教:您OSS上传文件成功后什么通知给App服务器存SQL数据库?纠结的是:1. 如果是上传之后通知,万一App服务器暂时不可用,OSS上的文件不就是永久垃圾了;2. 如果是上传之前通知,OSS上传失败得在删除一遍;不知如何是好,作者有何种建议?

        Ps:工程名称建议还是英文吧?:stuck_out_tongue_winking_eye:
      • qyhlj:感谢分享

      本文标题:2017 iOS 阿里云OSS上传音频,视频,多图,单图完整版

      本文链接:https://www.haomeiwen.com/subject/actjhxtx.html