iOS 文件上傳

關(guān)鍵代碼記錄

    NSDictionary *params = @{@"type" : @"1"};
    GODebugLog(@"path : %@", path);

/// ********************************************************************************
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: path] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
    // 1、組裝 http body ===================
    // ①定義分界線(boundary)
    NSString *boundaryID = [[NSString stringWithFormat:@"boundary_cba_cfrdce_%@_%@", @(arc4random()), @(arc4random())] md5]; // 分界線標識符
    NSString *boundary = [NSString stringWithFormat:@"--%@", boundaryID]; // 分界線
    NSString *boundaryEnding = [NSString stringWithFormat:@"--%@--", boundaryID]; // 分界線結(jié)束
    
    // ②圖片data
    NSData *imgData = UIImageJPEGRepresentation(pic, 0.5);
    
    // ③http body的字符串
    NSMutableString *bodyString = [NSMutableString string];
    // 遍歷keys,組裝文本類型參數(shù)
    NSArray *keys = [params allKeys];
    for (NSString *key in keys) {
        // 添加分界線聊浅,換行
        [bodyString appendFormat:@"%@\r\n", boundary];
        // 添加參數(shù)名稱奏瞬,換2行
        [bodyString appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
        // 添加參數(shù)的值,換行
        [bodyString appendFormat:@"%@\r\n", [params objectForKey:key]];
    }
    // 添加分界線侄刽,換行
    [bodyString appendFormat:@"%@\r\n", boundary];
    // 組裝文件類型參數(shù), 換行
    NSString *fileParamName = @"file"; // 文件參數(shù)名
    NSString *filename = @"avatar.jpg"; // 文件名
    [bodyString appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fileParamName, filename];
    // 聲明上傳文件的格式衷模,換2行
    NSString *fileType = @"image/jpeg";
    [bodyString appendFormat:@"Content-Type: %@\r\n\r\n", fileType];
    
    // 聲明 http body data
    NSMutableData *bodyData = [NSMutableData data];
    // 將 body 字符串 bodyString 轉(zhuǎn)化為UTF8格式的二進制數(shù)據(jù)
    NSData *bodyParamData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
    [bodyData appendData:bodyParamData];
    // 將 image 的 data 加入
    [bodyData appendData:imgData];
    
    [bodyData appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // image數(shù)據(jù)添加完后 加一個換行
    
    // 分界線結(jié)束符加入(以 NSData 形式)
    NSString *boundryEndingWithReturn = [NSString stringWithFormat:@"%@\r\n", boundaryEnding]; // 分界線結(jié)束符加換行
    NSData *boundryEndingData = [boundryEndingWithReturn dataUsingEncoding:NSUTF8StringEncoding];
    [bodyData appendData:boundryEndingData];
    // 設(shè)置 http body data
    request.HTTPBody = bodyData;
    // 組裝 http body 結(jié)束 ===================
    
    // 設(shè)置 http header 中的 Content-Type 的值
    NSString *content = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundaryID];
    [request setValue:content forHTTPHeaderField:@"Content-Type"];
    // 設(shè)置 Content-Length
    [request setValue:[NSString stringWithFormat:@"%@", @(bodyData.length)] forHTTPHeaderField:@"Content-Length"];
    // 設(shè)置請求方式 POST
    request.HTTPMethod = @"POST";
    
// 三種方式都可以發(fā)起請求

   #if 0 // NSURLConnection
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        GODebugLog(@"response : %@", response);
        GODebugLog(@"data : %@", data);
        GODebugLog(@"connectionError : %@", connectionError);
        
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"dic : %@", dic);
        success(dic);
    }];
    
#elif 1 // NSURLSessionUploadTask
    
    NSURLSessionUploadTask *uploadTask = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        GODebugLog(@"data : %@", data);
        GODebugLog(@"response : %@", response);
        GODebugLog(@"error : %@", error);
        
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"dic : %@", dic);
        
        success(dic);
        
    }];
    [uploadTask resume];
#else // NSURLSessionDataTask
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        GODebugLog(@"data : %@", data);
        GODebugLog(@"response : %@", response);
        GODebugLog(@"error : %@", error);
        
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"dic : %@", dic);
        
        success(dic);

    }];
    [dataTask resume];
#endif

前一種方式拼接方式為將所有參數(shù)及參數(shù)的值(除去文件參數(shù))拼接成一個NSString鹊汛,然后再一起轉(zhuǎn)換為NSData,也可以將每一個參數(shù)和參數(shù)值分別轉(zhuǎn)換為NSData阱冶,逐個將NSData拼接到一起刁憋,兩種方式結(jié)果是一致的。

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
    [request setHTTPShouldHandleCookies:NO];
    [request setTimeoutInterval:30];
    [request setHTTPMethod:@"POST"];

    NSString *boundaryID = [[NSString stringWithFormat:@"boundary_cba_cfrdce_%@_%@", @(arc4random()), @(arc4random())] md5]; // 分界線標識符

    // set Content-Type in HTTP header
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundaryID];
    [request setValue:contentType forHTTPHeaderField: @"Content-Type"];

    // post body
    NSMutableData *body = [NSMutableData data];

    // add params (all params are strings)
    for (NSString *param in params) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundaryID] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"%@\r\n", [params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
    }
    
    if (imageData) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundaryID] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", @"file"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:imageData];
        [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    }

    [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundaryID] dataUsingEncoding:NSUTF8StringEncoding]];

    // setting the body of the post to the reqeust
    [request setHTTPBody:body];

    // set the content-length
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[body length]];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];

    // set URL
    [request setURL:[NSURL URLWithString: path]];

    // 三種方式都可以發(fā)起請求

   #if 0 // NSURLConnection
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        GODebugLog(@"response : %@", response);
        GODebugLog(@"data : %@", data);
        GODebugLog(@"connectionError : %@", connectionError);
        
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"dic : %@", dic);
        success(dic);
    }];
    
#elif 1 // NSURLSessionUploadTask
    
    NSURLSessionUploadTask *uploadTask = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        GODebugLog(@"data : %@", data);
        GODebugLog(@"response : %@", response);
        GODebugLog(@"error : %@", error);
        
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"dic : %@", dic);
        
        success(dic);
        
    }];
    [uploadTask resume];
#else // NSURLSessionDataTask
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        GODebugLog(@"data : %@", data);
        GODebugLog(@"response : %@", response);
        GODebugLog(@"error : %@", error);
        
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"dic : %@", dic);
        
        success(dic);

    }];
    [dataTask resume];
#endif

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末木蹬,一起剝皮案震驚了整個濱河市至耻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌镊叁,老刑警劉巖尘颓,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異晦譬,居然都是意外死亡疤苹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門敛腌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卧土,“玉大人,你說我怎么就攤上這事像樊∮容海” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵生棍,是天一觀的道長颤霎。 經(jīng)常有香客問我,道長涂滴,這世上最難降的妖魔是什么友酱? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮氢妈,結(jié)果婚禮上粹污,老公的妹妹穿的比我還像新娘。我一直安慰自己首量,他們只是感情好壮吩,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著加缘,像睡著了一般鸭叙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拣宏,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天沈贝,我揣著相機與錄音,去河邊找鬼勋乾。 笑死宋下,一個胖子當著我的面吹牛嗡善,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播学歧,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼罩引,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了枝笨?” 一聲冷哼從身側(cè)響起袁铐,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎横浑,沒想到半個月后剔桨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡徙融,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年洒缀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片张咳。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡帝洪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出脚猾,到底是詐尸還是另有隱情葱峡,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布龙助,位于F島的核電站砰奕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏提鸟。R本人自食惡果不足惜军援,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望称勋。 院中可真熱鬧胸哥,春花似錦、人聲如沸赡鲜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽银酬。三九已至嘲更,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揩瞪,已是汗流浹背赋朦。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宠哄。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓壹将,卻偏偏與公主長得像,于是被迫代替她去往敵國和親琳拨。 傳聞我的和親對象是個殘疾皇子瞭恰,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

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