在同一个 NSURLRequest 中发送 JSON 数组和 UIImageView

Posted

技术标签:

【中文标题】在同一个 NSURLRequest 中发送 JSON 数组和 UIImageView【英文标题】:Sending JSON array and UIImageView in the same NSURLRequest 【发布时间】:2015-12-14 20:39:17 【问题描述】:

我目前正尝试在同一个 NSURLRequest 中发送一个 JSON 数组和一个 UIImageView,以避免对我的数据库进行多次网络调用。按照其他答案中给出的建议,我在 Objective C 中编写了一个函数,如下所示:

    NSDictionary *textFields = [NSDictionary dictionaryWithObjectsAndKeys:self.reviewTexfField.text, @"review",
self.rateView.rating, @"grade", nil];

    if([NSJSONSerialization isValidJSONObject:textFields])


            NSError* error;
            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:textFields options:0 error:&error];
            NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[jsonData length]];
            NSURL *url = [NSURL URLWithString:@"http://domain.something/file.php"];
            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
            NSString *boundary = @"---------------------------14737809831466499882746641449";
            NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; application/json; boundary=%@", boundary];
            [request addValue:contentType forHTTPHeaderField:@"Content-Type"];
            [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
            [request setValue:postLength forHTTPHeaderField:@"Content-Length"];

            [request setHTTPMethod:@"POST"];

            NSMutableData *body = [NSMutableData data];

            // Appending image.
            NSString *imageName = @"A name";
            [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

            [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"photo\"; filename=\"%@.jpg\"\r\n", imageName] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

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

            NSData *imageData = UIImageJPEGRepresentation(self.immagineRecensione.image, 0.5);
            [body appendData:imageData];


            //Appending JSON request
            [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [request setHTTPBody:jsonData];
                  [body appendData:[[NSString stringWithFormat:@"\r\n--\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

            NSLog(@"%@", [request allHTTPHeaderFields]);
            NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
            NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
            [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse* response, NSError *error)
            
                NSString *response= [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
                NSLog(@"%@", response);

                if(!error) NSLog(@"Done \n");

            ] resume];

        

从服务器端,我编写了一个 php(5.0,已弃用,但仅用于练习目的)脚本:

    <?php

        $con = mysql_connect("something", "username", "password");
        if(!$con)
            die("Error during connection" . mysql_error());

        $db_selected = mysql_select_db("DB", $con);

        $uploaddir = "./aFolder/";
        $user = basename($_FILES['photo']['name']);
        $storeName = $uploaddir.$user;
        echo $storeName. "\n ";

        if (move_uploaded_file($_FILES['photo']['tmp_name'], $uploadfile))
            echo 'The photo has been inserted in the database\n';
         else die("The photo hasn't been copied. \n " . mysql_error());


        $jsondata = file_get_contents('php://input');
        $textFields = json_decode($jsondata, true);

        $review = $data['review'];
        $grade = $data['grade'];

        //Echoing for debug purposes
        echo $review . " " . $grade . "\n ";

        mysql_close($con);
?>

我面临的问题是我没有从服务器端收到任何信息:可以建立连接,但似乎没有发送任何字段。我应该想要实现的是,我可以将图像复制到数据库内的文件夹中,并检索包含 JSON 数组中发送的两个字段文本的响应,并从服务器回显。

【问题讨论】:

【参考方案1】:

您应该选择 JSON 请求(在这种情况下,您需要将图像作为 base64 编码的字符串包含在内)或多部分请求(在这种情况下,您只需包含两个字符串值作为请求的附加部分),但不是两者兼而有之。如果我要发送一些非常丰富的结构(例如嵌套的字典数组),我可能会使用 JSON,但是在这里给出简单的结构(两个字符串),我倾向于一个简单的多部分请求。

不幸的是,上面的多部分请求的构建并不完全正确。我建议您参考https://***.com/a/24252378/1271826,它可以上传文件以及提供文本字段。或者考虑使用像AFNetworking 这样的框架,它可以让你摆脱困境或创建这个请求。

在服务器上处理响应方面,由于客户端代码指定它将接受 JSON 响应,我假设您希望服务器构建这样的响应。有关mysqliPDO_MySQL 的示例,请参阅https://***.com/a/20196541/1271826 中的第2 点(特别是,不使用代码示例中已弃用的mysql 接口;请参阅http://php.net/manual/en/intro.mysql.php)代码

收到multi-part/formdata 请求, escapes 的值或 ? 绑定, 将数据插入您的数据库,并 然后构建 JSON 响应。

显然,您仍会在原始代码 sn-p 中使用 move_uploaded_file 接收文件,但您可以使用 $_POST 参数访问这两个文本字段,并且您可以取消用于的 file_get_contents('php://input') 模式仅限 JSON 请求。

【讨论】:

以上是关于在同一个 NSURLRequest 中发送 JSON 数组和 UIImageView的主要内容,如果未能解决你的问题,请参考以下文章

NSURLRequest 出错,无法识别的选择器发送到实例

NSURLRequest : 发布数据并读取发布的页面

从 NSURLRequest 以编程方式按下 html 按钮

为 NSURLRequest 创建一个 cookie?

iOS开发网络篇--NSURLConnection

iOS开发网络篇—NSURLConnection基本使用