1.NSMutableURLRequest的设置
//创建NSMutableURLRequest对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//设置请求类型
[request setHTTPMethod:@"POST"];
//设置超时时间
[request setTimeoutInterval:60];
//设置缓存策略
[request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
//设置Base64认证
NSString *authString = [[[NSString stringWithFormat:@"%@:%@",kGlobal.userInfo.sAccount,kGlobal.userInfo.sPassword] dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0]; authString = [NSString stringWithFormat: @"Basic %@", authString]; [request setValue:authString forHTTPHeaderField:@"Authorization"];
//设置POST方法需要传递的参数
NSString *paramStr = [NSString stringWithFormat:@"PostID=%@&Name=%@&Text=%@",self.uuID,kGlobal.userInfo.sApplyName,self.textView.text]; NSData *bodyData = [paramStr dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPBody:bodyData];
2.创建网络会话
//创建网络会话
NSURLSession *session = [NSURLSession sharedSession];
3.创建网络请求(本文介绍 NSURLSessionDataTask 和 NSURLSessionUploadTask 两种)
//方案一:使用NSURLSessionDataTask请求网络数据
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error == nil) { NSLog(@"文字发布成功!"); NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;//将response对象强制转换为NSHTTPURLResponse,可以获取HTTP响应报文的头信息,如响应代码200表示请求成功可以用(httpResponse.statusCode获取) NSLog(@"返回的Response:%@",httpResponse); NSError *error = nil; //而真正的HTTP响应的Body内容则需要序列化获取 NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];//返回一个字典类型数据 //NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];//返回一个JSON数组 //NSArray *array = [NSJSONSerialization JSONObjectWithData:[[dic valueForKey:@"Pictures"] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];//[dic valueForKey:@"Pictures"]得到的是第一次解析得到的JSON Array的字符串,需要二次解析成JSON的数组
if (!error) { NSLog(@"返回信息:%@",dic); } }else{ NSLog(@"发布失败,代码%@",error); }}];
4.发送网络请求
[task resume];
//方案二:使用NSURLSessionUploadTask请求网络数据,NSURLSessionUploadTask 和 NSURLSessionDataTask的不同之处在于NSURLSessionUploadTask更像Web的表单提交,例如模拟Web表单的图片上传可以使用NSURLSessionUploadTask。
NSURLSessionUploadTask *dataTask = [session uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {if (error == nil) { NSLog(@"发布成功!"); NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; NSLog(@"statusCode:%lu",httpResponse.statusCode); NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); if (picNum == self.imgsArray.count) { [SVProgressHUD showSuccessWithStatus:kTXT(@"IMUploadSuccess")]; [self dismissViewControllerAnimated:YES completion:nil]; } }else{ NSLog(@"发布失败,代码%@!",error); }}];
上面发送网络请求的方法和方法一的不同之处在于bodyData的构建,方法二的bodyData是模拟HTTP的报文结构来的,使用NSData来拼接HTTP报文。
//bodyData的构建方法
- (NSData *)getBodydataWithImage:(UIImage *)image { //把文件转换为NSData NSData *fileData = UIImageJPEGRepresentation(image, 1.0); NSString *fileName=[Global getUniqueStrByUUID]; //1.构造body string NSMutableString *bodyString = [[NSMutableString alloc] init]; //2.拼接body string //(1)file_name [bodyString appendFormat:@"--%@\r\n",boundry]; [bodyString appendFormat:@"Content-Disposition: form-data; name=\"FileName\"\r\n"]; [bodyString appendFormat:@"Content-Type: text/plain; charset=\"utf-8\"\r\n\r\n"]; [bodyString appendFormat:@"aaa%@.jpg\r\n",fileName]; //(2)PostID [bodyString appendFormat:@"--%@\r\n",boundry]; [bodyString appendFormat:@"Content-Disposition: form-data; name=\"PostID\"\r\n"]; [bodyString appendFormat:@"Content-Type: text/plain; charset=\"utf-8\"\r\n\r\n"]; [bodyString appendFormat:@"%@\r\n",self.uuID]; //(3)pic [bodyString appendFormat:@"--%@\r\n",boundry]; [bodyString appendFormat:@"Content-Disposition: form-data; name=\"pic\"; filename=\"%@.jpg\"\r\n",fileName]; [bodyString appendFormat:@"Content-Type: image/jpeg\r\n\r\n"]; //[bodyString appendFormat:@"Content-Type: application/octet-stream\r\n\r\n"]; //3.string --> data NSMutableData *bodyData = [NSMutableData data]; //拼接的过程 //前面的bodyString, 其他参数 [bodyData appendData:[bodyString dataUsingEncoding:NSUTF8StringEncoding]]; //图片数据 [bodyData appendData:fileData]; //4.结束的分隔线 NSString *endStr = [NSString stringWithFormat:@"\r\n--%@--\r\n",boundry]; //拼接到bodyData最后面 [bodyData appendData:[endStr dataUsingEncoding:NSUTF8StringEncoding]]; return bodyData; }
整个bodyData的构建过程原理根据HTTP报文上传图片时,格式用boundory进行分割,但是每次HTTP报文的boundory的值是不一样的,这里为了方便就定义一个固定值,其实固定值也是可以上传成功,亲测有效。HTTP的body体里面把文字和图片内容用boundory和换行符进行分割,分区发送,邮件内容也是类似,所以只要遵循HTTP报文的格式,就可以模拟HTTP报文上传图片。
//boundry的设置
static NSString *boundry = @"----------V2ymHFg03ehbqgZCaKO6jy";//设置边界
//[Global getUniqueStrByUUID]是工具类的方法,用于产生一个GUID,具体的方法明细如下:
+ (NSString *)getUniqueStrByUUID { CFUUIDRef uuidObj = CFUUIDCreate(nil);//create a new UUID //get the string representation of the UUID NSString *uuidString = (__bridge_transfer NSString *)CFUUIDCreateString(nil, uuidObj); CFRelease(uuidObj); return uuidString ; }
时间: 2024-10-24 05:33:39