七牛云服務(wù)器上傳服務(wù)

版本記錄

版本號(hào) 時(shí)間
V1.0 2017.04.20

前言

最近正在做一個(gè)項(xiàng)目撒璧,要用到七牛的云存儲(chǔ)服務(wù)哥遮,例如注冊(cè)賬號(hào)的時(shí)候需要上傳注冊(cè)者的頭像,這個(gè)時(shí)候我們主要就是將圖像上傳到七牛服務(wù)器美澳,服務(wù)器吐給我們一個(gè)URL销部,然后我們將圖片的URL傳給服務(wù)器摸航,服務(wù)器存儲(chǔ)的就是這個(gè)圖片的外接URL地址。
??下面是兩個(gè)鏈接:
??七牛官方文檔
??七牛github地址

七牛SDK概覽

這里我就以上傳圖片為例子進(jìn)行說明七牛服務(wù)器上傳服務(wù)的原理舅桩。至于視頻音頻等的原理都類似酱虎。七牛可以從cocoapods上獲取和集成擂涛。我們先看一下七牛主要的框架文件读串。

七牛文檔1
七牛文檔2

這里上傳主要就是采用QNUploadManager這個(gè)類。

七牛SDK詳述

SDK環(huán)境適配

七湃雎瑁現(xiàn)在已經(jīng)更新到7.1版本恢暖,他依賴于AFNetworking框架,對(duì)ios系統(tǒng)和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|

我們先看一下上傳文件的實(shí)例代碼挟阻。

#import <QiniuSDK.h>
...
NSString *token = @"從服務(wù)端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 編碼訪問七牛云存儲(chǔ)將反饋錯(cuò)誤。

SDK幾個(gè)重要參數(shù)

1.option參數(shù)

關(guān)于 option 參數(shù)附鸽,一般情況下脱拼,開發(fā)者可以忽略 put 方法中的 option 參數(shù),即在調(diào)用時(shí)保持 option 的值為 nil 即可坷备。但對(duì)于一些特殊的場(chǎng)景熄浓,我們可以給 option 傳入一些高級(jí)選項(xiàng)以更精確的控制上傳行為和獲取進(jìn)度信息。option QNUploadOption 類型包含的變量有:params省撑、mimeType赌蔑、checkCrc、progressHandler竟秫、cancelSignal娃惯。

2.param參數(shù)

用戶自定義參數(shù),必須以 x:開頭肥败,這些參數(shù)可以作為變量用于 upToken 的 callbackBody趾浅、returnBody、asyncOps 參數(shù)中馒稍,具體信息請(qǐng)參閱自定義變量皿哨。 一個(gè)簡(jiǎn)單的例子如下:

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參數(shù)

為上傳文件設(shè)置一個(gè)自定義的 MIME 類型,如果為空纽谒,那么服務(wù)端自動(dòng)檢測(cè)文件的 MIME 類型证膨。

4. checkCrc參數(shù)

checkCrc 為 NO 時(shí),服務(wù)端不會(huì)校驗(yàn) crc32 值鼓黔,checkCrc 為 YES 時(shí)央勒,服務(wù)端會(huì)計(jì)算上傳文件的 crc32 值不见,然后與用戶提供的 crc32 參數(shù)值比較確認(rèn)文件的完整性,如果校驗(yàn)失敗會(huì)返回 406 錯(cuò)誤订歪。

5. 上傳進(jìn)度監(jiān)測(cè)和取消上傳

這里利用的就是block來獲得上傳進(jìn)度和取消上傳脖祈。

上傳的block為


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

如果實(shí)現(xiàn)了這個(gè) block肆捕,并作為 option 參數(shù)傳入刷晋,會(huì)及時(shí)得到上傳進(jìn)度通知。

取消上傳的block為

typedef BOOL (^QNUpCancellationSignal)(void);

如果希望中途可以取消上傳慎陵,需要實(shí)現(xiàn)上面的 block眼虱,并作為參數(shù)傳入 option。

6. 斷點(diǎn)續(xù)傳

SDK 實(shí)現(xiàn)了斷點(diǎn)續(xù)上傳席纽,如果需要保存上傳進(jìn)度捏悬,需要您在生成 UploaderManager 實(shí)例時(shí)傳入一個(gè)實(shí)現(xiàn)保存進(jìn)度的代理,SDK 自帶了將進(jìn)度保存進(jìn)文件的方法润梯,您可以自己實(shí)現(xiàn)其他保存方式过牙。

NSError *error;

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

//check error

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

SDK實(shí)際使用

我舉一個(gè)例子說明使用七牛的情況吧,在修改個(gè)人資料的時(shí)候纺铭,需要用戶上傳自己的頭像寇钉,上傳頭像可以使用七牛的云存儲(chǔ)。具體步驟為:

  • 客戶端和服務(wù)端分別集成SDk舶赔;
  • 向自己的后臺(tái)服務(wù)器發(fā)送請(qǐng)求扫倡,獲取uploadToken;
  • 對(duì)接uploadManager類進(jìn)行上傳,這里有好幾個(gè)方法可以使用竟纳,需要我們傳遞uploadToken和key撵溃,其中key可以自己隨便指定一個(gè)字符串,也可以傳nil锥累,傳遞nil則七牛自動(dòng)為我們生成缘挑。

下面我就直接上大體上的代碼了。

1. 打開本地相冊(cè)獲取圖像

#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. 請(qǐng)求自己的服務(wù)器獲取uploadToken

//從本地服務(wù)器請(qǐng)求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);
    }];

}

//調(diào)用網(wǎng)絡(luò)工具桶略,我們這次用的是get請(qǐng)求

- (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. 看結(jié)果


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";
}

然后我們登錄七牛云空間查看結(jié)果

七牛云空間結(jié)果

我存儲(chǔ)了好幾個(gè)都成功了语淘。

后記

七牛簡(jiǎn)單的上傳任務(wù)并不難,用戶還可以自定義配置上傳删性,比如選擇上傳的服務(wù)器亏娜,華北華南等。還有設(shè)置是否需要返回上傳進(jìn)度和取消上傳蹬挺,斷點(diǎn)續(xù)傳等维贺。這需要大家在業(yè)務(wù)中慢慢的對(duì)接。謝謝大家對(duì)我的支持巴帮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末溯泣,一起剝皮案震驚了整個(gè)濱河市虐秋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垃沦,老刑警劉巖客给,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異肢簿,居然都是意外死亡靶剑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門池充,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桩引,“玉大人,你說我怎么就攤上這事收夸】咏常” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵卧惜,是天一觀的道長(zhǎng)厘灼。 經(jīng)常有香客問我,道長(zhǎng)咽瓷,這世上最難降的妖魔是什么设凹? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮忱详,結(jié)果婚禮上围来,老公的妹妹穿的比我還像新娘。我一直安慰自己匈睁,他們只是感情好监透,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著航唆,像睡著了一般胀蛮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上糯钙,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天粪狼,我揣著相機(jī)與錄音,去河邊找鬼任岸。 笑死再榄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的享潜。 我是一名探鬼主播困鸥,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼剑按!你這毒婦竟也來了疾就?” 一聲冷哼從身側(cè)響起澜术,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎猬腰,沒想到半個(gè)月后鸟废,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姑荷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年盒延,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厢拭。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兰英,死狀恐怖撇叁,靈堂內(nèi)的尸體忽然破棺而出供鸠,到底是詐尸還是另有隱情,我是刑警寧澤陨闹,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布楞捂,位于F島的核電站,受9級(jí)特大地震影響趋厉,放射性物質(zhì)發(fā)生泄漏寨闹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一君账、第九天 我趴在偏房一處隱蔽的房頂上張望繁堡。 院中可真熱鬧,春花似錦乡数、人聲如沸椭蹄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)绳矩。三九已至,卻和暖如春玖翅,著一層夾襖步出監(jiān)牢的瞬間翼馆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工金度, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留应媚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓猜极,卻偏偏與公主長(zhǎng)得像中姜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子魔吐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 點(diǎn)擊查看原文 Web SDK 開發(fā)手冊(cè) SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)...
    layjoy閱讀 13,758評(píng)論 0 15
  • 上傳文件是我們?cè)谇岸碎_發(fā)中經(jīng)常遇到的一個(gè)問題扎筒。最近在做某項(xiàng)目管理后臺(tái)的時(shí)候莱找,需要將輪播圖上傳至七牛云。以前在Vue...
    iliuqiang閱讀 6,210評(píng)論 12 16
  • 數(shù)據(jù)問題 Q:使用Tunnel Java SDK上傳數(shù)據(jù)嗜桌,上傳數(shù)據(jù)可以自動(dòng)分配到各個(gè)分區(qū)嗎奥溺? A:目前Tunnel...
    許此一生閱讀 2,481評(píng)論 0 0
  • 最近做項(xiàng)目用到了七牛云存儲(chǔ),就講一下如何使用springMVC對(duì)視頻上傳到七牛云上骨宠。 Java SDK依賴的第三方...
    遠(yuǎn)向閱讀 4,459評(píng)論 1 3
  • 首先作為一名曾經(jīng)的英語(yǔ)老師浮定,我要為思維導(dǎo)圖在英語(yǔ)學(xué)習(xí)以及英語(yǔ)教學(xué)中的應(yīng)用種草。思維導(dǎo)圖會(huì)幫助英語(yǔ)學(xué)習(xí)變得輕松快樂层亿。...
    Cynthia叢閱讀 374評(píng)論 0 0