I'm trying to learn AFNetworking, and I've taken a sample from their Github. I don't know what parameters to set in dataToPostusing the the php I have. I'm new to Objective-C and php. Can someone take a look at my snippet and my php to see what I'm missing. It's hard to find "upload" tutorials for AFNetworking, but there are TONS of JSON tutorials out there.

I want to use a NSMutableURLRequest because eventually I would like to upload from an array or UITableview; here is mt code so far:

PHP:

<?php 
header("Content-Type: application/json");

$uploaddir = './';      //Uploading to same directory as PHP file
$file = basename($_FILES['userfile']['name']);
$uploadFile = $file;
$randomNumber = rand(0, 99999); 
$newName = $uploadDir . $randomNumber . $uploadFile;


if (!is_uploaded_file($_FILES['userfile']['tmp_name'])) { 
     $result = array("success" => false);  
      echo json_encode($result);  
      exit();
}

if ($_FILES['userfile']['size']> 300000) {
    $result = array("success" => false, "message" =>"the uploaded file is too big");  
          echo json_encode($result);  
          exit(); 
}

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $newName)) {
    $postsize = ini_get('post_max_size');   //Not necessary, I was using these
    $canupload = ini_get('file_uploads');    //server variables to see what was 
    $tempdir = ini_get('upload_tmp_dir');   //going wrong.
    $maxsize = ini_get('upload_max_filesize');
    //echo "http://localhost:8888/upload/{$file}" . "\r\n" . $_FILES['userfile']['size'] . "\r\n" . $_FILES['userfile']['type'] ;
    $result = array("success"   => true,
                "code"      => 0,
                "message"   => "success",
                "postsize"  => $postsize,
                "canupload" => $canupload,
                "tempdir"   => $tempdir,
                "maxsize"   => $maxsize);
    echo json_encode($result);
}
?>

Xcode:

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

// 2. Create an NSMutableURLRequest.
NSMutableURLRequest *request =
[serializer multipartFormRequestWithMethod:@"POST" URLString:@"http://my.com/upload/upload.php"
                                parameters:nil
                 constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                     [formData appendPartWithFileData:imageData
                                                 name:@"userfile"
                                             fileName:@"myimage.jpg"
                                             mimeType:@"image/jpeg"];
                 }];

// 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,
                                    NSInteger totalBytesWritten,
                                    NSInteger totalBytesExpectedToWrite) {
    NSLog(@"Wrote %ld/%ld", (long)totalBytesWritten, (long)totalBytesExpectedToWrite);
}];

// 5. Begin!
[operation start];

ERROR (resolved):

2014-03-31 15:37:46.921 TestingUpload[7190:60b] Wrote 32768/59063
2014-03-31 15:37:46.922 TestingUpload[7190:60b] Wrote 59063/59063
2014-03-31 15:37:46.923 TestingUpload[7190:60b] Wrote 32768/59063
2014-03-31 15:37:46.923 TestingUpload[7190:60b] Wrote 59063/59063
2014-03-31 15:37:46.925 TestingUpload[7190:60b]     Success {
    canupload = 1;
    code = 0;
    maxsize = 32M;
    message = success;
    postsize = 32M;
    success = 1;
    tempdir = "/Applications/MAMP/tmp/php";
}
2014-03-31 15:37:46.927 TestingUpload[7190:60b]     Success {
    canupload = 1;
    code = 0;
    maxsize = 32M;
    message = success;
    postsize = 32M;
    success = 1;
    tempdir = "/Applications/MAMP/tmp/php";
}

Thanks for any help and explanation. Thank you!

有帮助吗?

解决方案

Your PHP is looking for the field name userfile, but your Objective-C is using attachment. You must use the same field name on both platforms. I also assume the "<$php" was just a typo and that you intended "<?php".

A couple of other improvements you might want to consider:

  1. I would suggest that you might want to change your PHP to return JSON rather than just writing text strings. It will be easier for your Objective-C code to parse the responses and differentiate between various errors and success.

    For example, your if successful, your PHP might do the following:

    $result = array("success" => true, "code" => 0, "message" => "success");
    

    Or if you wanted to log those additional values, as in your existing code sample, you could:

    $result = array("success"   => true,
                    "code"      => 0,
                    "message"   => "success",
                    "postsize"  => $postsize,
                    "canupload" => $canupload,
                    "tempdir"   => $tempdir,
                    "maxsize"   => $maxsize);
    

    If unsuccessful, you might do:

    $result = array("success" => false, "code" => 1, "message" => "file not found");
    

    or

    $result = array("success" => false, "code" => 2, "message" => "file too large");
    

    Regardless of which $result is chosen, when done, you should JSON encode it and echo it (rather than echoing the simple text string):

    echo json_encode($result);
    

    Clearly, use whatever codes and messages you want, but the idea is to return JSON, which can be easily parsed to determine if the upload request was successful, and if not, then why. Trying to parse simple text responses from the server will be inherently fragile.

    Anyway, your Objective-C can then parse this response and just check the success or code values and handle these scenarios appropriately.

  2. I would not suggest having the PHP save the uploads in the same folder as the PHP, itself. At the very least, I'd create a dedicated subdirectory for the uploads. I'd personally choose a directory completely outside the web server's directory structure.

其他提示

On the basis of your updated code sample and reported warnings/errors, I have a few observations:

  1. You are receiving the message about multipartFormRequestWithMethod being deprecated because you're using the rendition without the error parameter, but that's been replaced with another rendition with this additional parameter. See the declaration of this method in AFURLRequestSerialization.h for more information.

  2. Your error about the text/html is a result of the fact that PHP is sending a response with a header that reports a Content-type of text/html. If your PHP script is not sending JSON back in your PHP, you have to change your your Objective-C code so it knows to expect an HTTP response (by default, it expects JSON back):

    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    

    That tells the AFHTTPRequestOperationManager to accept any HTTP response back from the server.

    Alternatively, if you change your PHP to return JSON (and you should, IMHO), you need to not only change the PHP code to echo the json_encode of the results, but also inform PHP to specify the appropriate Content-Type in the header. So before you echo any JSON in your PHP), add the following line to the PHP code:

    header("Content-Type: application/json");
    
  3. You said:

    I thought the content type was defined in mimetype

    The mimetype defines the Content-type for that part of the multipart request. But the whole request has its own Content-type header, too. The response also bears a Content-type setting in its header. This error, is telling you that the response bore a Content-type of text/html, and it expected application/json. (See my prior point regarding fixing that.)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top