POST jpeg upload with AFNetworking

15,653

Try this snippet of code:

    NSData* sendData = [self.fileName.text dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *sendDictionary = [NSDictionary dictionaryWithObject:sendData forKey:@"name"];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:remoteUrl];
    NSMutableURLRequest *afRequest = [httpClient multipartFormRequestWithMethod:@"POST" 
                                                                           path:@"/photos" 
                                                                     parameters:sendDictionary 
                                                      constructingBodyWithBlock:^(id <AFMultipartFormData>formData) 
                                      {                                     
                                          [formData appendPartWithFileData:photoImageData 
                                                                      name:self.fileName.text 
                                                                  fileName:filePath 
                                                                  mimeType:@"image/jpeg"]; 
                                      }
                                      ];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];
    [operation setUploadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {

        NSLog(@"Sent %d of %d bytes", totalBytesWritten, totalBytesExpectedToWrite);

    }];

    [operation setCompletionBlock:^{
        NSLog(@"%@", operation.responseString); //Gives a very scary warning
    }];

    [operation start]; 
Share:
15,653
Will Larche
Author by

Will Larche

Software Engineer on Material Components

Updated on June 15, 2022

Comments

  • Will Larche
    Will Larche almost 2 years

    I can't for the life of me figure out why this doesn't work when I use AFNetworking. It worked with ASIHTTP. This is all very new to me. But I can't figure out why the files are not being transferred from $_FILES to the server's HD anymore. Here's the iOS code:

    - (IBAction)uploadPressed 
    {
    [self.fileName resignFirstResponder];
    NSURL *remoteUrl = [NSURL URLWithString:@"http://mysite.com"];
    
    NSTimeInterval timeInterval = [NSDate timeIntervalSinceReferenceDate];
    NSString *photoName=[NSString stringWithFormat:@"%lf-Photo.jpeg",timeInterval];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    
    // the path to write file
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:photoName];
    NSData * photoImageData = UIImageJPEGRepresentation(self.remoteImage.image, 1.0);
    [photoImageData writeToFile:filePath atomically:YES];
    
    NSLog(@"photo written to path: e%@", filePath);
    
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:remoteUrl];
    NSMutableURLRequest *afRequest = [httpClient multipartFormRequestWithMethod:@"POST" 
                                                                           path:@"/photos" 
                                                                     parameters:nil 
                                                      constructingBodyWithBlock:^(id <AFMultipartFormData>formData) 
                                      {
                                          [formData appendPartWithFormData:[self.fileName.text dataUsingEncoding:NSUTF8StringEncoding] 
                                                                      name:@"name"];
    
    
                                          [formData appendPartWithFileData:photoImageData 
                                                                      name:self.fileName.text 
                                                                  fileName:filePath 
                                                                  mimeType:@"image/jpeg"]; 
                                      }
                                      ];
    
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];
    [operation setUploadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
    
        NSLog(@"Sent %d of %d bytes", totalBytesWritten, totalBytesExpectedToWrite);
    
    }];
    
       [operation setCompletionBlock:^{
        NSLog(@"%@", operation.responseString); //Gives a very scary warning
    }];
    
    [operation start];    
    
    
    
    }
    

    I used to do this:

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:remoteUrl];
    [request setPostValue:self.fileName.text forKey:@"name"];
    [request setFile:filePath forKey:@"filename"];
    [request setDelegate:self];
    [request startAsynchronous];
    

    Here's my PHP:

     {
    // these could be stored in a .ini file and loaded
    // via parse_ini_file()... however, this will suffice
    // for an example
    $codes = Array(
        100 => 'Continue',
        101 => 'Switching Protocols',
        200 => 'OK',
        201 => 'Created',
        202 => 'Accepted',
        203 => 'Non-Authoritative Information',
        204 => 'No Content',
        205 => 'Reset Content',
        206 => 'Partial Content',
        300 => 'Multiple Choices',
        301 => 'Moved Permanently',
        302 => 'Found',
        303 => 'See Other',
        304 => 'Not Modified',
        305 => 'Use Proxy',
        306 => '(Unused)',
        307 => 'Temporary Redirect',
        400 => 'Bad Request',
        401 => 'Unauthorized',
        402 => 'Payment Required',
        403 => 'Forbidden',
        404 => 'Not Found',
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        407 => 'Proxy Authentication Required',
        408 => 'Request Timeout',
        409 => 'Conflict',
        410 => 'Gone',
        411 => 'Length Required',
        412 => 'Precondition Failed',
        413 => 'Request Entity Too Large',
        414 => 'Request-URI Too Long',
        415 => 'Unsupported Media Type',
        416 => 'Requested Range Not Satisfiable',
        417 => 'Expectation Failed',
        500 => 'Internal Server Error',
        501 => 'Not Implemented',
        502 => 'Bad Gateway',
        503 => 'Service Unavailable',
        504 => 'Gateway Timeout',
        505 => 'HTTP Version Not Supported'
    );
    
    return (isset($codes[$status])) ? $codes[$status] : '';
    }
    
    function sendResponse($status = 200, $body = '', $content_type = 'text/html')
    {
    $status_header = 'HTTP/1.1 ' . $status . ' ' . getStatusCodeMessage($status);
    header($status_header);
    header('Content-type: ' . $content_type);
    echo $body;
    }
    
    if (!empty($_FILES) && isset($_POST["name"])) {
                $name = $_POST["name"];
                $tmp_name = $_FILES['filename']['tmp_name'];
                $uploads_dir = '/var/www/cnet/photos';
                move_uploaded_file($tmp_name, "$uploads_dir/$name.jpg");
                $result = array("SUCCEEDED");
                sendResponse(200, json_encode($result));
                } else {
    
                sendResponse(400, 'Nope');
                }
    ?>
    
  • Will Larche
    Will Larche over 12 years
    I adjusted the code above to be most recent. Verified that the PHP works. I am trying to do the completion block but it won't let me log operation.responsString. What should I put in the block instead?
  • Will Larche
    Will Larche over 12 years
    Ach! I got the completion block to work. It's giving me "Nope" which means they are at least communicating to each other. But I'm getting a 400 response. So the code says that either $_FILES is empty or $_POST['name'] is not set. I also added in the @"name" appendPartWithFormData. You can see above all the most recent of both. So this form data is not being sent just right yet.
  • jeswang
    jeswang over 10 years
    But if there is some way to use it without warning?
  • jeswang
    jeswang over 10 years
    After we update to 2.0, there is no AFHTTPClient and using Igor Fedorchuk's code gets an warning, any new apis?