send UIImage to HTTP server Objective C

I send an image to a server HTTP with this code:

-(NSDictionary*)sendImage:(UIImage*)image withDescription:(NSString*)description andTarget:(NSString*)target andTargetId:(int)targetId {
    __block NSDictionary *result = nil;
    NSData *imageData = UIImagePNGRepresentation(image);
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", PREFIX_URL_REQUEST, SEND_IMAGE]]];
    [request setHTTPMethod:REQUEST_TYPE_POST];
    NSString *boundary = [[NSString alloc] init];
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
    NSMutableData *body = [NSMutableData data];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@.%d\"rn", target, targetId] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Type: application/%@.png\r\n\r\n", [NSString stringWithFormat:@"%@_%d", target, targetId]] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:imageData]];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:body];
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        result = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSLog(@"%@", result.description);
        dispatch_semaphore_signal(sem);
    }];
    [dataTask resume];
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    return result;
}


this is the server code:

session_start();
if ( isset($_SESSION['username']) ) {
    $params = explode(".", basename($_FILES["file"]["name"]));
    $target = array_values($params)[0];
    $id = array_values($params)[1];
    if ( ($target == "profile") || ($target == "question" && $_SESSION["waitingImagesQuestion"] > 0) || ($target == "answer" && $_SESSION["waitingImagesAnswer"] > 0) ) {
        $imageDirectory = "images/".round(microtime(true)*1000).".png";
        if ( move_uploaded_file($_FILES["file"]["tmp_name"], $imageDirectory) ) {
            switch ( $target ) {
                case "profile":
                    print JsonBuilder::putRecordProfileImage($imageDirectory);
                    return;
                case "answer":
                    $_SESSION["waitingImagesAnswer"] --;
                    print JsonBuilder::putRecordAnswerImage($imageDirectory, $id);
                    return;
                case "question":
                    $_SESSION["waitingImagesQuestion"] --;
                    print JsonBuilder::putRecordQuestionImage($imageDirectory, $id);
                    return;
            }
        }
    }
}
print JsonBuilder::getStringError();



works, but only when I call the client method so (

[UIImage imageNamed:@"aaa.png"]
):


[sender sendImage:[UIImage imageNamed:@"aaa.png"] withDescription:@"" andTarget:@"profile" andTargetId:1];


if I call the method with an UIImage (for example a photo taken from the camera roll), so:

-(void)sendImage:(UIImage*)image { 
     return [sender sendImage:image withDescription:@"" andTarget:@"profile" andTargetId:1]; 
}



doesn't work! Why?



Thanks

Answered by Franco7Scala in 128305022

now it works:


-(NSDictionary*)sendImage:(UIImage*)image withDescription:(NSString*)description andTarget:(NSString*)target andTargetId:(int)targetId {
    if ( image != nil ) {
        NSData *imageData = UIImageJPEGRepresentation(image, 0.33f);
        __block NSDictionary *result = nil;
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", PREFIX_URL_REQUEST, SEND_IMAGE]]];
        [request setHTTPMethod:REQUEST_TYPE_POST];
        NSString *boundary = @"0xKhTmLbOuNdArY";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
        [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
        NSMutableData *body = [NSMutableData data];
        [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@.%d\"rn", target, targetId] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Type: application/%@.png\r\n\r\n", [NSString stringWithFormat:@"%@_%d", target, targetId]] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[NSData dataWithData:imageData]];
        [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [request setHTTPBody:body];
        dispatch_semaphore_t sem = dispatch_semaphore_create(0);
        NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            result = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            dispatch_semaphore_signal(sem);
        }];
        [dataTask resume];
        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
        return result;
    }
    return nil;
}

Define "doesn't work". What debugging steps have you taken?


Since you're not assigning any value to "boundary", not sure how that will look when converted to a string - perhaps the data that "doesn't work" happens to contain that string, which messes up the multipart form? Just a wild guess.

the problem isn't the boundary!

note that: if I give an image to the method so:
[UIImage imageNamed:@"aaa.png"]
it works!


if I give an image so:


-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
imageSelected = [info objectForKey:UIImagePickerControllerOriginalImage]; selectedImage = YES;
}
}


where the image is "imageSelected" doesn't work!

I don’t think we’ll be able to offer you any concrete advice without knowing more about the failure. To repeat junkpile’s question, what do you mean by “doesn’t work”? What are the actual symptoms? Do you get an transport error (that is, a

-URLSession:task:didCompleteWithError:
callback with a non-nil error value)? Do you get an HTTP-level error from the server? Or do you just see the wrong results on the server?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Accepted Answer

now it works:


-(NSDictionary*)sendImage:(UIImage*)image withDescription:(NSString*)description andTarget:(NSString*)target andTargetId:(int)targetId {
    if ( image != nil ) {
        NSData *imageData = UIImageJPEGRepresentation(image, 0.33f);
        __block NSDictionary *result = nil;
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", PREFIX_URL_REQUEST, SEND_IMAGE]]];
        [request setHTTPMethod:REQUEST_TYPE_POST];
        NSString *boundary = @"0xKhTmLbOuNdArY";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
        [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
        NSMutableData *body = [NSMutableData data];
        [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@.%d\"rn", target, targetId] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Type: application/%@.png\r\n\r\n", [NSString stringWithFormat:@"%@_%d", target, targetId]] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[NSData dataWithData:imageData]];
        [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [request setHTTPBody:body];
        dispatch_semaphore_t sem = dispatch_semaphore_create(0);
        NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            result = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            dispatch_semaphore_signal(sem);
        }];
        [dataTask resume];
        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
        return result;
    }
    return nil;
}
send UIImage to HTTP server Objective C
 
 
Q