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

  • 相关阅读:
    Could A New Linux Base For Tablets/Smartphones Succeed In 2017?
    使用libhybris,glibc和bionic共存时的TLS冲突的问题
    6 Open Source Mobile OS Alternatives To Android in 2018
    Using MultiROM
    GPU drivers are written by the GPU IP vendors and they only provide Android drivers
    Jolla Brings Wayland Atop Android GPU Drivers
    How to Use Libhybris and Android GPU Libraries with Mer (Linux) on the Cubieboard
    闲聊Libhybris
    【ARM-Linux开发】wayland和weston的介绍
    Wayland and X.org problem : Why not following the Android Solution ?
  • 原文地址:https://www.cnblogs.com/rayshen/p/4604219.html
Copyright © 2011-2022 走看看