七牛云服务器上传服务

版本记录

版本号 时间
V1.0 2017.04.20

前言

最近正在做一个项目,要用到七牛的云存储服务,例如注册账号的时候需要上传注册者的头像,这个时候我们主要就是将图像上传到七牛服务器,服务器吐给我们一个URL,然后我们将图片的URL传给服务器,服务器存储的就是这个图片的外接URL地址。
  下面是两个链接:
  七牛官方文档
  七牛github地址

七牛SDK概览

这里我就以上传图片为例子进行说明七牛服务器上传服务的原理。至于视频音频等的原理都类似。七牛可以从cocoapods上获取和集成。我们先看一下七牛主要的框架文件。

七牛文档1
七牛文档2

这里上传主要就是采用QNUploadManager这个类。

七牛SDK详述

SDK环境适配

七牛现在已经更新到7.1版本,他依赖于AFNetworking框架,对ios系统和xcode版本也有要求。需要一定的搭配,具体如下。

|SDK版本|最低ios版本|最低OSX版本|Xcode版本|
|:----:|:----:|:----:|:----:|:---:|
|7.1/AFN-3.x|ios7|OS X10.9|xoode 6|
|7.0/AFN-2.x|ios6|OS X10.8|xoode 5|
|7.x/AFN-1.x|ios5|OS X10.7|xoode 5|
|6.x/AFN-1.x|ios6|None|xoode 5|

我们先看一下上传文件的实例代码。

#import <QiniuSDK.h>
...
NSString *token = @"从服务端SDK获取";
QNUploadManager *upManager = [[QNUploadManager alloc] init];
NSData *data = [@"Hello, World!" dataUsingEncoding : NSUTF8StringEncoding];
[upManager putData:data key:@"hello" token:token
complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
NSLog(@"%@", info);
NSLog(@"%@", resp);
} option:nil];
...
//注意:key 及所有需要输入的字符串必须采用 utf8 编码,如果使用非 utf8 编码访问七牛云存储将反馈错误。

SDK几个重要参数

1.option参数

关于 option 参数,一般情况下,开发者可以忽略 put 方法中的 option 参数,即在调用时保持 option 的值为 nil 即可。但对于一些特殊的场景,我们可以给 option 传入一些高级选项以更精确的控制上传行为和获取进度信息。option QNUploadOption 类型包含的变量有:params、mimeType、checkCrc、progressHandler、cancelSignal。

2.param参数

用户自定义参数,必须以 x:开头,这些参数可以作为变量用于 upToken 的 callbackBody、returnBody、asyncOps 参数中,具体信息请参阅自定义变量。 一个简单的例子如下:

QNUploadOption *opt = [[QNUploadOption alloc] initWithMime:@"text/plain" progressHandler:nil params:@{ @"x:foo":@"fooval" } checkCrc:YES cancellationSignal:nil];
[upManager putData:data key:@"hello" token:token
complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
 NSLog(@"%@", info);
NSLog(@"%@", resp);
} option:opt];

3.mineType参数

为上传文件设置一个自定义的 MIME 类型,如果为空,那么服务端自动检测文件的 MIME 类型。

4. checkCrc参数

checkCrc 为 NO 时,服务端不会校验 crc32 值,checkCrc 为 YES 时,服务端会计算上传文件的 crc32 值,然后与用户提供的 crc32 参数值比较确认文件的完整性,如果校验失败会返回 406 错误。

5. 上传进度监测和取消上传

这里利用的就是block来获得上传进度和取消上传。

上传的block为


typedef void (^QNUpProgressHandler)(NSString *key, float percent);

如果实现了这个 block,并作为 option 参数传入,会及时得到上传进度通知。

取消上传的block为

typedef BOOL (^QNUpCancellationSignal)(void);

如果希望中途可以取消上传,需要实现上面的 block,并作为参数传入 option。

6. 断点续传

SDK 实现了断点续上传,如果需要保存上传进度,需要您在生成 UploaderManager 实例时传入一个实现保存进度的代理,SDK 自带了将进度保存进文件的方法,您可以自己实现其他保存方式。

NSError *error;

QNFileRecorder *file = [QNFileRecorder fileRecorderWithFolder:@"保存目录" error:&error];

//check error

QNUploadManager *upManager = [[QNUploadManager alloc] initWithRecorder:file];

SDK实际使用

我举一个例子说明使用七牛的情况吧,在修改个人资料的时候,需要用户上传自己的头像,上传头像可以使用七牛的云存储。具体步骤为:

  • 客户端和服务端分别集成SDk;
  • 向自己的后台服务器发送请求,获取uploadToken;
  • 对接uploadManager类进行上传,这里有好几个方法可以使用,需要我们传递uploadToken和key,其中key可以自己随便指定一个字符串,也可以传nil,传递nil则七牛自动为我们生成。

下面我就直接上大体上的代码了。

1. 打开本地相册获取图像

#pragma mark - UIImagePickerControllerDelegate

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    [picker dismissViewControllerAnimated:YES completion:nil];
    self.uploadImage = info[UIImagePickerControllerOriginalImage];
    self.infoFillView.avatarImage = self.uploadImage;
    
    [self getTokenFromMyServer];
    
}

2. 请求自己的服务器获取uploadToken

//从本地服务器请求token
    
- (void)getTokenFromMyServer
{
    NSMutableDictionary *dictParam = [NSMutableDictionary dictionary];
    [dictParam setObject:[JJConfig myProfile].token forKey:@"token"];
    [dictParam setObject:@"1" forKey:@"version"];
    NSString *serverURL = [NSString stringWithFormat:@"%@%@",kDomainURL,kLoginUploadImageToMyServer];
    
    [[JJNetWorkManager manager] requestByGetNetworkWithServerUrl:serverURL parameters:dictParam success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            NSLog(@"%@",responseObject);
            if ([[responseObject objectForKey:@"code"] integerValue] == 0) {
                NSDictionary *dataDict = [responseObject objectForKey:@"data"];
                self.uploadToken = [dataDict objectForKey:@"uploadToken"];
                self.uploadZone = [dataDict objectForKey:@"zone"];

                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    [self uploadImageToQiniu];
                });
            }
    } error:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"%@",error);
    }];

}

//调用网络工具,我们这次用的是get请求

- (void)requestNetworkWithServerUrl:(NSString * _Nonnull)serverUrl parameters:(nullable id)parameters success:(successRequestBlock)successBlock error:(errorRequestBlock)errorBlock {
    
    self.sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
    self.sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
    [self.sessionManager.requestSerializer setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [self.sessionManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    self.sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
    self.sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
    [self.sessionManager.requestSerializer setValue:[ZBConfig myProfile].token forHTTPHeaderField:@"token"];
    [self.sessionManager.requestSerializer setValue:@"1" forHTTPHeaderField:@"version"];
    
    [self.sessionManager GET:serverUrl parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        DDLogVerbose(@"\nRequest URL: %@\nResponse: \n%@",task.currentRequest.URL,responseObject);
        successBlock(task,responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        DDLogError(@"\nRequest URL: %@\nErrorInfo :\n%@ \nError:%@",task.currentRequest.URL,error.localizedDescription,error);
        errorBlock(task,error);
    }];
}

3. 上传图片到七牛

//上传图片到七牛
    
- (void)uploadImageToQiniu
{
    QNConfiguration *congfiguration = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
        builder.zone = [QNZone zone1];
    }];

    QNUploadManager *uploadManager = [[QNUploadManager alloc] initWithConfiguration:congfiguration];
    NSData *imageData = nil;
    if (UIImagePNGRepresentation(self.uploadImage) == nil) {
        imageData = UIImageJPEGRepresentation(self.uploadImage, 1.0);
    }
    else {
        imageData = UIImagePNGRepresentation(self.uploadImage);
    }

    [uploadManager putData:imageData key:nil token:self.uploadToken complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
        if (info.ok) {
            NSLog(@"成功");
        }
        else {
            NSLog(@"失败");
        }
        NSLog(@"info---%@",info);
        NSLog(@"key---%@",key);
        NSLog(@"resp---%@",resp);

    } option:nil];
    
}

4. 看结果


2017-04-21 20:37:01.229916 ------[3346:678850] 成功
2017-04-21 20:37:01.230149 ------3346:678850] info---<QNResponseInfo= id: F967882A-963F-4E66-91BB-2F643B386F96, ver: 7.1.5, status: 200, requestId: fGgAAMnGNhHiabcU, xlog: body:16;s.ph;s.put.tw;s.put.tr:17;s.put.tw;s.put.tr:18;s.ph;s.put.tw;s.put.tr:19;s.ph;PFDS:20;PFDS:20;PFDS:21;rs9_4.sel/not found;rdb.g/no such key;DBD/404;v4.get/Document not found;rs9_4.ins;rwro.ins:1;mc.s;RS:1;rs.put:2;rs-upload.putFile:26;UP:45, xvia: (null), host: upload-z1.qiniu.com ip: 111.206.234.140 duration: 1.298980 s time: 1492778221 error: (null)>
2017-04-21 20:37:01.230222 ------[3346:678850] key---(null)
2017-04-21 20:37:01.230333 ------[3346:678850] resp---{
    hash = "FgG8rxrG-vftWFCsE-Ru04QW1j7u";
    key = "FgG8rxrG-vftWFCsE-Ru04QW1j7u";
}

然后我们登录七牛云空间查看结果

七牛云空间结果

我存储了好几个都成功了。

后记

七牛简单的上传任务并不难,用户还可以自定义配置上传,比如选择上传的服务器,华北华南等。还有设置是否需要返回上传进度和取消上传,断点续传等。这需要大家在业务中慢慢的对接。谢谢大家对我的支持。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,996评论 0 15
  • 上传文件是我们在前端开发中经常遇到的一个问题。最近在做某项目管理后台的时候,需要将轮播图上传至七牛云。以前在Vue...
    iliuqiang阅读 6,268评论 12 16
  • 数据问题 Q:使用Tunnel Java SDK上传数据,上传数据可以自动分配到各个分区吗? A:目前Tunnel...
    许此一生阅读 2,522评论 0 0
  • 最近做项目用到了七牛云存储,就讲一下如何使用springMVC对视频上传到七牛云上。 Java SDK依赖的第三方...
    远向阅读 4,503评论 1 3
  • 首先作为一名曾经的英语老师,我要为思维导图在英语学习以及英语教学中的应用种草。思维导图会帮助英语学习变得轻松快乐。...
    Cynthia丛阅读 388评论 0 0