- iOS开发-七牛SDK断点上传功能的封装
公司的某些业务使用的是七牛云储存,要把一些文件(视频)直传到七牛服务器
七牛SDK文档地址
https://developer.qiniu.com/kodo/sdk/1240/objc
在这里就不写怎么集成SDK了,可以按照文档集成,推荐使用Cocoapods
按照文档实现简单的上次功能(未封装)
NSString *token = @"从服务端SDK获取";
NSString * key = @"指定七牛服务上的文件名,或nil";
NSString * filePath = @"要上传的文件路径";
QNConfiguration *config =[QNConfiguration build:^(QNConfigurationBuilder *builder) {
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:[QNResolver systemResolver]];
QNDnsManager *dns = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
//是否选择 https 上传
builder.zone = [[QNAutoZone alloc] initWithHttps:YES dns:dns];
//设置断点续传
NSError *error;
builder.recorder = [QNFileRecorder fileRecorderWithFolder:[NSTemporaryDirectory() stringByAppendingString:@"YDUploadFileRecord"] error:&error];
}];
// 上传过程中实时执行此函数
QNUploadOption *uploadOption = [[QNUploadOption alloc]initWithMime:nil progressHandler:^(NSString *key, float percent) {
// 上传进度
DLog(@"%f",percent)
} params:nil checkCrc:NO cancellationSignal:^BOOL{
//上传中途取消函数 如果想取消,返回True, 否则返回No
return NO;
}];
QNUploadManager *uploadManager = [[QNUploadManager alloc]initWithConfiguration:config];
[uploadManager putFile: filePath key: key token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
DLog(@"info == %@",info);
DLog(@"key == %@",key);
DLog(@"resp == %@",resp);
} option:uploadOption];
这样就可以实现简单的上传,控制台打印信息
info == <QNResponseInfo= id: 4A31DEA6-59F3-43EE-BC94-DD8EE3C5FB9F, ver: 7.1.5, status: 200, requestId: VEUAADXpmnETONMU, xlog: s.ph;s.ph;s.ph;PFDS;PFDS;PFDS;PTFDM:3;s.gh;PFDS/613;s.gh;PFDS/613;s.gh;PFDS/613;PTFDM;PTFDS;rs11_6.sel/not found;rs10_6.sel/not found;rdb.g/no such key;DBD/404;v4.get:1/Document not found;rs11_6.ins;rwro.ins:2;mc.s;mc.d/404;mc.d/404;RS:3;rs.put:4;UP:15, xvia: (null), host: up-z1.qbox.me ip: (null) duration: 0.073756 s time: 1500604757 error: (null)>
key == (null)
resp == {
hash = "lpbhBcvgB0-fgPlNagatMlBn0o72";
key = "lpbhBcvgB0-fgPlNagatMlBn0o72";
}
上述的key = lpbhBcvgB0-fgPlNagatMlBn0o72,就是你上传文件的访问路径(需要拼接上域名)
- 注意点
如果不配置QNConfiguration,而直接使用下面的方式就会报错
QNUploadOption *uploadOption = [[QNUploadOption alloc]initWithMime:nil progressHandler:^(NSString *key, float percent) {
// 上传进度
DLog(@"%f",percent)
} params:nil checkCrc:NO cancellationSignal:^BOOL{
//上传中途取消函数 如果想取消,返回True, 否则返回No
return NO;
}];
NSError *error;
QNFileRecorder *file = [QNFileRecorder fileRecorderWithFolder:@"YDUploadFileRecord" error:&error];
QNUploadManager *uploadManager = [[QNUploadManager alloc]initWithRecorder:file];
[uploadManager putFile:path key:nil token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
DLog(@"info == %@",info);
DLog(@"key == %@",key);
DLog(@"resp == %@",resp);
} option:uploadOption];
控制台打印信息
info == <QNResponseInfo= id: 4A31DEA6-59F3-43EE-BC94-DD8EE3C5FB9F, ver: 7.1.5, status: 400, requestId: vgMAADJg5tejONMU, vgMAADJg5tejONMU, xlog: RA:124.160.115.109:80;UP/400;NUPROXY:65/400, xvia: (null), host: upload.qiniu.com ip: 61.162.231.199 duration: 0.123475 s time: 1500605377 error: Error Domain=qiniu.com Code=400 "(null)" UserInfo={error=incorrect region, please use up-z1.qiniu.com}>
key == (null)
resp == (null)
仔细分析info中的信息,大概是当前上传空间是
upload.qiniu.com
, 请使用up-z1.qiniu.com
空间
仔细阅读七牛文档你会看到 :
注意: 如使用最新版的sdk(7.1.4),可自动判断上传空间。按如下方式使用:
QNConfiguration *config =[QNConfiguration build:^(QNConfigurationBuilder *builder) {
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:[QNResolver systemResolver]];
QNDnsManager *dns = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
//是否选择 https 上传
builder.zone = [[QNAutoZone alloc] initWithHttps:YES dns:dns];
//设置断点续传
NSError *error;
builder.recorder = [QNFileRecorder fileRecorderWithFolder:@"保存目录" error:&error];
}];
这样基本的上传就完成了
对七牛SDK的封装(基于单个文件的上传)
YDUploadFile(用于记录本次上传的关键信息)
- YDUploadFile.h
@interface YDUploadFile : NSObject
@property (nonatomic, strong) NSString* filePath;
@property (nonatomic, strong) NSString *key;
@property (nonatomic, strong) NSString *token;
- (instancetype)initWithFile:(NSString *)filePath key:(NSString *)key token:(NSString *)token;
@end
- YDUploadFile.m
@implementation YDUploadFile
- (instancetype)initWithFile:(NSString *)filePath key:(NSString *)key token:(NSString *)token {
if (self = [self init]) {
self.filePath = filePath;
self.key = key;
self.token = token;
}
return self;
}
@end
YDUploadManager 断点续传的单例类
- block回调一下上传信息(上传进度.上传完成)
/**
* 上传完成后的回调函数
*
* @param info 上下文信息,包括状态码,错误值
* @param key 上传时指定的key,原样返回
* @param resp 上传成功会返回文件信息,失败为nil; 可以通过此值是否为nil 判断上传结果
*/
typedef void (^YDUpCompletionHandler)(QNResponseInfo *info, NSString *key, NSDictionary *resp);
/**
* 上传进度回调函数
*
* @param key 上传时指定的存储key
* @param percent 进度百分比
*/
typedef void (^YDUpProgressHandler)(NSString *key, float percent);
- 单例
//单例
+ (instancetype)defaultUploader;
- 上传方法,取消上传,继续上传
/**
* 上传文件
*
* @param filePath 文件路径
* @param key 上传到云存储的key,为nil时表示是由七牛生成
* @param token 上传需要的token, 由服务器生成
* @param completionHandler 上传完成后的回调函数
* @param progressHandler 上传进度回调函数
*/
- (void)uploadFile:(NSString *)filePath
key:(NSString *)key
token:(NSString *)token
progressHandler:(YDUpProgressHandler)progressHandler
complete:(YDUpCompletionHandler)completionHandler;
//取消上传某个文件;
- (void)cancelUpload;
//继续上传某个文件
- (void)continueUpload;
YDUploadManager.m文件
懒加载QNUploadManager
- (QNUploadManager *)upmanager {
if (_upmanager == nil) {
QNConfiguration *config =[QNConfiguration build:^(QNConfigurationBuilder *builder) {
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:[QNResolver systemResolver]];
QNDnsManager *dns = [[QNDnsManager alloc] init:array networkInfo:[QNNetworkInfo normal]];
//是否选择 https 上传
builder.zone = [[QNAutoZone alloc] initWithHttps:YES dns:dns];
//设置断点续传
NSError *error;
builder.recorder = [QNFileRecorder fileRecorderWithFolder:[NSTemporaryDirectory() stringByAppendingString:@"YDUploadFileRecord"] error:&error];
}];
_upmanager = [[QNUploadManager alloc]initWithConfiguration:config];
}
return _upmanager;
}
- 关键上传方法
- (void)uploadFile:(NSString *)filePath
key:(NSString *)key
token:(NSString *)token
progressHandler:(YDUpProgressHandler)progressHandler
complete:(YDUpCompletionHandler)completionHandler {
self.file = [[YDUploadFile alloc]initWithFile:filePath key:key token:token];
self.completionHandler = completionHandler;
self.progressHandler = progressHandler;
[self uploadFile:filePath key:key token:token];
}
- (void)uploadFile:(NSString *)filePath key:(NSString *)key token:(NSString *)token {
// 记录本次上传任务
self.cancelFlag = NO;
// 上传过程中实时执行此函数
QNUploadOption *uploadOption = [[QNUploadOption alloc]initWithMime:nil progressHandler:^(NSString *key, float percent) {
// 上传进度
self.percent = percent;
// 上传进度
self.progressHandler(key, percent);
} params:nil checkCrc:NO cancellationSignal:^BOOL{
//上传中途取消函数 如果想取消,返回True, 否则返回No
return self.cancelFlag;
}];
[self.upmanager putFile:filePath key:key token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
// 完成回调
self.completionHandler(info, key, resp);
if (info.ok) { // 请求成功
self.file = nil;
}else{ // 请求失败, 这里可以把info信息上报自己的服务器,便于后面分析上传错误原因
}
} option:uploadOption];
}
- 取消上传方法
// 取消上传
- (void)cancelUpload {
self.cancelFlag = YES;
}
- 继续上传
// 继续上传
- (void)continueUpload {
self.cancelFlag = NO;
[self uploadFile:self.file.filePath key:self.file.key token:self.file.token];
}
- 注意点:
取消上传方法: 官方文档有写的 上传中途取消函数 typedef BOOL (^QNUpCancellationSignal)(void);return 如果想取消,返回True, 否则返回No
- 一句话上传文件
[[YDUploadManager defaultUploader] uploadFile:path key:key token:token progressHandler:^(NSString *key, float percent) {
DLog(@"===上传进度===%f",percent);
} complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
DLog(@"info == %@",info);
DLog(@"key == %@",key);
DLog(@"resp == %@",resp);
if (info.ok) {// 成功
// 给服务器发送关键信息
}else{ // 失败
}
}];
本文中有可能会出现知识错误,欢迎大家讨论,交流
多文件上传可以参考下面博客,我是参考修改的
-
参考博客