版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.04.20 |
前言
最近正在做一個項目,要用到七牛的云存儲服務,例如注冊賬號的時候需要上傳注冊者的頭像,這個時候我們主要就是將圖像上傳到七牛服務器,服務器吐給我們一個URL,然后我們將圖片的URL傳給服務器,服務器存儲的就是這個圖片的外接URL地址。
??下面是兩個鏈接:
??七牛官方文檔
??七牛github地址
七牛SDK概覽
這里我就以上傳圖片為例子進行說明七牛服務器上傳服務的原理。至于視頻音頻等的原理都類似。七牛可以從cocoapods上獲取和集成。我們先看一下七牛主要的框架文件。
這里上傳主要就是采用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";
}
然后我們登錄七牛云空間查看結果
我存儲了好幾個都成功了。
后記
七牛簡單的上傳任務并不難,用戶還可以自定義配置上傳,比如選擇上傳的服務器,華北華南等。還有設置是否需要返回上傳進度和取消上傳,斷點續傳等。這需要大家在業務中慢慢的對接。謝謝大家對我的支持。