1

I'm currently trying to send a JSON array and an UIImageView in the same NSURLRequest in order to avoid multiple network calls to my database. Following the suggests given in the other answers, I've written a function in Objective C which is the following:

    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];

        }
}

From the server side, I've written a php (5.0, deprecated but it's just for just for excercise purposes) script which is:

    <?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);
?>

The problem I'm facing is that I don't receive nothing from the server side: the connection can be estabilished but it seems like neither feilds are sent. What I should want to achieve is that I can copy the image in a folder inside my database and retrieving a response which contains the text of the two fields sent in the JSON array, echoed from the server.

Gab
  • 87
  • 3
  • 7

1 Answers1

0

You should choose either JSON request (in which case you'd include the image as a base64-encoded string) or multipart request (in which are you'd just include the two string values as additional parts of the request), but not both. I might use JSON if I was sending some very rich structure (e.g. nested array of dictionaries), but give the simple structure here (two strings), I'd lean towards a simple multipart request.

Unfortunately, the building of the multipart request, above, isn't quite right. I'd refer you to https://stackoverflow.com/a/24252378/1271826, which can upload files as well as supply text fields. Or consider using a framework like AFNetworking, which gets you out of the weeds or creating this request.

In terms of processing the response on the server, since the client code specified that it would accept a JSON response, I assume you'd like the server to build such response. See point #2 in https://stackoverflow.com/a/20196541/1271826 for an example of mysqli or PDO_MySQL (notably, not using the deprecated mysql interface from your code sample; see http://php.net/manual/en/intro.mysql.php) code that

  • receives multi-part/formdata request,
  • escapes the values or does ? binding,
  • inserts data into your database, and
  • then builds JSON responses.

Obviously, you would still receive the file using the move_uploaded_file in your original code snippet, but you access these two text fields using $_POST parameters and you can retire that file_get_contents('php://input') pattern, which is used for JSON requests only.

Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044