[iOS AFNetworking框架实现HTTP请求、多文件图片上传下载]
简单的JSON的HTTP传输就不说了,看一个简单的DEMO吧。
主要明白parameters是所填参数,类型是字典型。我把这部分代码封装起来了,以便多次调用。也许写在一起更清楚点。
#pragma mark - JSON方式post提交数据 - (void)postJSONWithUrl:(NSString *)urlStr parameters:(id)parameters success:(void (^)(id responseObject))success fail:(void (^)())fail { AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; // 设置请求格式 manager.requestSerializer = [AFJSONRequestSerializer serializer]; // 设置返回格式 manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager POST:urlStr parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { //查看返回数据 //NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; if (success) { success(responseObject); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"%@", error); if (fail) { fail(); } }]; }
下面是调用方式:返回的json会存在id的变量里,这个jsondataAFN框架有自动转换成字典型,用健直接可以取到值。
//jason解析,根据上传id从数据库取出用户信息 -(void)jasontest{ //访问的URL NSString *url = @"http://localhost:8888/chepaishibie/selectuser.php"; //需要传进去的参数 NSDictionary *parameter = @{@"Driverid": @"10000"}; //GET或者POST请求 [[ShenAFN sharedInstance] JSONDataWithUrl:url parameter:parameter success:^(id jsondata) { //返回的字符,并输出 NSLog(@"success:\n%@", jsondata); //如果是其他字符,可以用以下语句解析返回的语句 //NSString *result = [[NSString alloc] initWithData:jsondata encoding:NSUTF8StringEncoding]; //如果是json格式,可以通过这种方式获取变量 id info1=jsondata[@"info1"]; _personname=info1[@"personname"]; } fail:^{ NSLog(@"请求失败"); }]; }
网上实现多图片的上传的教程几乎没,所以在这里特别说下。方便别人学习。
首先看下浏览器端的上传实现:http://www.w3school.com.cn/php/php_file_upload.asp
一般情况下for表单都是默认键值对传输的,当表单类型设置为enctype="multipart/form-data"时,传输会按照二进制传输。
PHP后台和W3C教程基本一样,我稍微改了下,用foreach就能实现动态的单个文件上传或者多个文件上传了。
说明一下,上传文件都放在$_FILES的数组里,获取方式$_FILES["file0"]或者$_FILES["file1"],这个file0就是再下面iOS工程里定义的name。
PHP后台代码如下:
<? header("Content-type: text/html; charset=UTF-8"); include("../configmysql.php"); mysql_select_db("chepaiDB",$q); //数据库 //POST获取键值对参数 $TEMPid=$_POST['Driverid']; echo "\nDriverid is ".$TEMPid."\n"; foreach ($_FILES as $_eachFile) { //file文件处理 if ($_eachFile["error"] > 0) { echo "错误: " . $_eachFile["error"] . "\n"; } else { echo "文件名: " . $_eachFile["name"] . "\n"; echo "类型: " . $_eachFile["type"] . "\n"; echo "大小: " . ($_eachFile["size"] / 1024) . " Kb\n"; } if (file_exists("uploadimage/" . $_eachFile["name"])) { echo $_eachFile["name"] . " 文件已经存在. "; } else { move_uploaded_file($_eachFile["tmp_name"], "uploadimage/" . $_eachFile["name"]); echo "文件已经被存储到: " . "uploadimage/" . $_eachFile["name"]."\n"; } } /* //file文件处理 if ($_FILES["file"]["error"] > 0) { echo "错误: " . $_FILES["file"]["error"] . "\n"; } else { echo "文件名: " . $_FILES["file"]["name"] . "\n"; echo "类型: " . $_FILES["file"]["type"] . "\n"; echo "大小: " . ($_FILES["file"]["size"] / 1024) . " Kb\n"; } if (file_exists("uploadimage/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " 文件已经存在. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"], "uploadimage/" . $_FILES["file"]["name"]); echo "文件已经被存储到: " . "uploadimage/" . $_FILES["file"]["name"]."\n"; } */ ?>
在AFN框架里,FORMDATA的体现,就是[manager POST:urlStr parameters:parameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {}这个函数是专门用于formData上传的,还可携带其他参数。
单图上传:
#pragma mark - 单个图片上传 - (void)uploadimgWithurl:(NSString *)urlStr image:(UIImage *)image fileName:(NSString *)fileName success:(void (^)(id responseObject))success fail:(void (^)())fail { //需要传递的参数,jason格式 NSDictionary *parameter = @{@"Driverid": @"10000"}; AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager POST:urlStr parameters:parameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { /*文件命名参考代码 // 在网络开发中,上传文件时,是文件不允许被覆盖,文件重名 // 要解决此问题, // 可以在上传时使用当前的系统事件作为文件名 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; // 设置时间格式 formatter.dateFormat = @"yyyyMMddHHmmss"; NSString *str = [formatter stringFromDate:[NSDate date]]; NSString *newfileName = [NSString stringWithFormat:@"%@.png", str]; */ [formData appendPartWithFileData:UIImagePNGRepresentation(image) name:@"file" fileName:fileName mimeType:@"image/png"]; } success:^(AFHTTPRequestOperation *operation, id responseObject) { if (success) { //NSLog(@"success\n"); success(responseObject); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { if (fail) { //NSLog(@"fail\n"); fail(); } }]; }
调用:
//单图片上传 -(void)uploadimg{ NSString *url = @"http://localhost:8888/chepaishibie/uploadimage.php"; UIImage *image=[UIImage imageNamed:@"swift"]; [[ShenAFN sharedInstance] uploadimgWithurl:url image:image fileName:@"myswift.png" success:^(id jsondata) { NSString *result = [[NSString alloc] initWithData:jsondata encoding:NSUTF8StringEncoding]; NSLog(@"%@", result); } fail:^{ NSLog(@"请求失败"); }]; }
多图片上传:主要是利用appendPartWithFileData函数,一个for循环把NSMutablearray里的图片都添加进去。
- (void)uploadMutableimgWithurl:(NSString *)urlStr imagearray:(NSMutableArray *)imgarray success:(void (^)(id responseObject))success fail:(void (^)())fail { //需要传递的参数,jason格式 NSDictionary *parameter = @{@"Driverid": @"10000"}; AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager POST:urlStr parameters:parameter constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { /*文件命名参考代码 // 在网络开发中,上传文件时,是文件不允许被覆盖,文件重名 // 要解决此问题, // 可以在上传时使用当前的系统事件作为文件名 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; // 设置时间格式 formatter.dateFormat = @"yyyyMMddHHmmss"; NSString *str = [formatter stringFromDate:[NSDate date]]; NSString *newfileName = [NSString stringWithFormat:@"%@.png", str]; */ for (int i=0; i<[imgarray count]; i++) { [formData appendPartWithFileData:UIImagePNGRepresentation([imgarray objectAtIndex:i]) name:[NSString stringWithFormat:@"file%d",i ] fileName:[NSString stringWithFormat:@"pic%d.png",i] mimeType:@"image/png"]; } } success:^(AFHTTPRequestOperation *operation, id responseObject) { if (success) { //NSLog(@"success\n"); success(responseObject); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { if (fail) { //NSLog(@"fail\n"); fail(); } }]; }
调用:
//多图片上传 -(void)uploadmutableimg{ NSString *url = @"http://localhost:8888/chepaishibie/uploadimage.php"; UIImage *image1=[UIImage imageNamed:@"0"]; UIImage *image2=[UIImage imageNamed:@"1"]; NSMutableArray *imgarray=[[NSMutableArray alloc]init]; [imgarray addObject:image1]; [imgarray addObject:image2]; [[ShenAFN sharedInstance] uploadMutableimgWithurl:url imagearray:imgarray success:^(id jsondata) { NSString *result = [[NSString alloc] initWithData:jsondata encoding:NSUTF8StringEncoding]; NSLog(@"%@", result); } fail:^{ NSLog(@"请求失败"); }]; }
另外JPEG的图片压缩可以用:
UIImageJPEGRepresentation(image,0.5);
GITHUB: https://github.com/rayshen/AFNDemo
___________________________________________________
专注iOS/前端开发,广泛涉猎多种平台和技术,欢迎交流
可以在微博关注并@沈z伟