zoukankan      html  css  js  c++  java
  • [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:
    %@", 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 "
    Driverid is ".$TEMPid."
    ";
    
        foreach ($_FILES as $_eachFile) {
            //file文件处理
            if ($_eachFile["error"] > 0)
              {
              echo "错误: " . $_eachFile["error"] . "
    ";
              }
            else
              {
              echo "文件名: " . $_eachFile["name"] . "
    ";
              echo "类型: " . $_eachFile["type"] . "
    ";
              echo "大小: " . ($_eachFile["size"] / 1024) . " Kb
    "; 
              }
             if (file_exists("uploadimage/" . $_eachFile["name"]))
                {
                  echo $_eachFile["name"] . " 文件已经存在. ";
                }
            else
                {
                  move_uploaded_file($_eachFile["tmp_name"],
                  "uploadimage/" . $_eachFile["name"]);
                  echo "文件已经被存储到: " . "uploadimage/" . $_eachFile["name"]."
    ";
                }
        }
        /*
        //file文件处理
        if ($_FILES["file"]["error"] > 0)
          {
          echo "错误: " . $_FILES["file"]["error"] . "
    ";
          }
        else
          {
          echo "文件名: " . $_FILES["file"]["name"] . "
    ";
          echo "类型: " . $_FILES["file"]["type"] . "
    ";
          echo "大小: " . ($_FILES["file"]["size"] / 1024) . " Kb
    "; 
          }
         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"]."
    ";
            }
        */
    ?>

    在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
    ");
                success(responseObject);
            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            if (fail) {
                //NSLog(@"fail
    ");
                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
    ");
                success(responseObject);
            }
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            if (fail) {
                //NSLog(@"fail
    ");
                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

  • 相关阅读:
    机房收费系统——视图的运用
    POJ 3278: Catch That Cow
    LeetCode 66 Plus One(加一)(vector)
    iOS定位服务CoreLocation
    Python 多线程
    LuaStudio编辑调试软件
    高仿快递100--实战之RadioGroup和RadioButton应用
    HDU
    MVC项目中怎样用JS导出EasyUI DataGrid为Excel
    调用getChildFragmentManager时出现的Bug
  • 原文地址:https://www.cnblogs.com/rayshen/p/4604219.html
Copyright © 2011-2022 走看看