Question

I'm trying to upload an image from my iOS App to my web server via PHP. Here is the following code:

-(void)uploadImage {
    NSData *imageData = UIImageJPEGRepresentation(image, 0.8);   

    //1
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

    //2
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];


    NSString *urlString = @"http://mywebserver.com/script.php";
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"POST"];
    NSString *boundary = @"---------------------------14737809831466499882746641449"
    ;
    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:[@"Content-Disposition: form-data; name=\"userfile\"; filename=\"iosfile.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:imageData]];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:body];

    //3
    self.uploadTask = [defaultSession uploadTaskWithRequest:request fromData:imageData];

    //4
    self.progressBarView.hidden = NO;
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

    //5
    [uploadTask resume];
}

// update the progressbar
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.progressBarView setProgress:(double)totalBytesSent / (double)totalBytesExpectedToSend animated:YES];
    });
}

// when finished upload
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {

    dispatch_async(dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        self.progressBarView.hidden = YES;
        [self.progressBarView setProgress:0.0];
    });

    if (!error) {
        // no error
        NSLog(@"no error");
    } else {
        NSLog(@"error");
        // error
    }

}

And the following working simple PHP code:

<?php
$msg = " ".var_dump($_FILES)." ";
$new_image_name = $_FILES["userfile"]["name"];
move_uploaded_file($_FILES["userfile"]["tmp_name"], getcwd() . "/pictures/" . $new_image_name);
?>

The application on iOS seems to upload the photo and the progressbar is working but I the file is not really uploaded when I check on the server files.

When I send the picture with the following code, it works perfectly (EDIT: but without the progressbar):

NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

And idea where I am wrong ?

Was it helpful?

Solution

Finally I used the AFNetworking library to handle this. As I haven't found clear methods to do this on the web and on stackoverflow, here is my answer to easily post user's images from their iOS device to your server via PHP. Majority of the code comes from this stackoverflow post.

-(void)uploadImage { 
    image = [self scaleImage:image toSize:CGSizeMake(800, 800)];
    NSData *imageData = UIImageJPEGRepresentation(image, 0.7);

    // 1. Create `AFHTTPRequestSerializer` which will create your request.
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];

    NSDictionary *parameters = @{@"your_param": @"param_value"};

    NSError *__autoreleasing* error;
    // 2. Create an `NSMutableURLRequest`.
    NSMutableURLRequest *request = [serializer multipartFormRequestWithMethod:@"POST" URLString:@"http://www.yoururl.com/script.php" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileData:imageData
                                    name:@"userfile"
                                fileName:@"image.jpg"
                                mimeType:@"image/jpg"];
    } error:(NSError *__autoreleasing *)error];
    // 3. Create and use `AFHTTPRequestOperationManager` to create an `AFHTTPRequestOperation` from the `NSMutableURLRequest` that we just created.
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    AFHTTPRequestOperation *operation =
    [manager HTTPRequestOperationWithRequest:request
                                     success:^(AFHTTPRequestOperation *operation, id responseObject) {
                                         NSLog(@"Success %@", responseObject);
                                     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                         NSLog(@"Failure %@", error.description);
                                     }];

    // 4. Set the progress block of the operation.
    [operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
                                        long long totalBytesWritten,
                                        long long totalBytesExpectedToWrite) {
        //NSLog(@"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite);
        [self.progressBarView setProgress:(double)totalBytesWritten / (double)totalBytesExpectedToWrite animated:YES];
    }];

    // 5. Begin!
    operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];


    self.progressView.hidden = NO;
    [operation start];
}

I think it will help new xcoders.

Cheers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top