3

Here's my slim framework php code

    $app->post('/uploadPicture', function () {

    if (!empty($_FILES)) {

        global $config;
        $picturePath = $config->get('db', 'picture');

        $allowedExts = array("jpg", "jpeg", "png");
        $extension = end(explode(".", $_FILES["file"]["name"]));

        if ($_FILES["file"]["type"] == "image/jpg" || $_FILES["file"]["type"] == "image/jpeg" || $_FILES["file"]["type"] == "image/png" && $_FILES["file"]["size"] < 2500000 && in_array($extension, $allowedExts)) {

            if ($_FILES["file"]["error"] > 0) {

                echo "Error: " . $_FILES["file"]["error"] . "<br />";
            } else {

                if (move_uploaded_file($_FILES['file']['tmp_name'], $picturePath . $_FILES["file"]["name"])) {
                    echo "success";
                }

            }
        } else {

            echo "Invalid file type";
        }
    } else {

        echo "no file to upload";
    }

});

This is what I'm using on the iphone side.

    -(void)uploadImage:(UIImage *)image withPersistentID:(NSString *)persistentID {

    [[MSMAMobileAPIClient sharedClient] POST:@"uploadPicture" parameters:nil constructingBodyWithBlock:^(id <AFMultipartFormData>formData) {

        NSData *imageData = UIImageJPEGRepresentation(image, 90);

        NSString *fileName = [NSString stringWithFormat:@"%@.jpg", persistentID];

        [formData appendPartWithFileData:imageData name:@"file" fileName:fileName mimeType:@"image/jpg"];

    } success:^(NSURLSessionDataTask * task, id responderData) {

        self.itemImageBlock(YES);

    } failure:^(NSURLSessionDataTask * task, NSError * error) {

        NSLog(@"%@",[error.userInfo objectForKey:@"JSONResponseSerializerWithDataKey"]);
        self.itemImageBlock(NO);

    }];

}

on the iphone side it just seems to hang like the server is busy and then it eventual fails with a timeout.

I've been using CocoaRestClient and am able to upload the image.

I also see the files being added to php's temp directory when attempting an upload from an iphone.

Am I doing something wrong?

EDIT: I just added an error log line to the uploadPicture function and it doens't even seem like it's being called by the iphone in the first place! :(

EDIT2: Here's the NSLog with the error message returned

Error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x17d6e1c0 {NSErrorFailingURLStringKey=https://192.168.1.15/mamobile/index.php/uploadPicture, NSErrorFailingURLKey=https://192.168.1.15/mamobile/index.php/uploadPicture, NSLocalizedDescription=The request timed out., NSUnderlyingError=0x17db1460 "The request timed out."}

EDIT3: I eliminated the slim php framework and just created a simple php script that only uploads a picture.

<?php 


if (!empty($_FILES)) {

    //load configuration file
    require_once 'Lite/Lite.php';
    $config = new Config_Lite('config.ini');
    $picturePath = $config->get('db', 'picture');

        $allowedExts = array("jpg", "jpeg", "png");
        $extension = end(explode(".", $_FILES["file"]["name"]));

        if ($_FILES["file"]["type"] == "image/jpg" || $_FILES["file"]["type"] == "image/jpeg" || $_FILES["file"]["type"] == "image/png" && $_FILES["file"]["size"] < 2500000 && in_array($extension, $allowedExts)) {

            if ($_FILES["file"]["error"] > 0) {

                echo "Error: " . $_FILES["file"]["error"] . "<br />";
            } else {

                if (move_uploaded_file($_FILES['file']['tmp_name'], $picturePath . $_FILES["file"]["name"])) {
                    echo "success";
                }

            }
        } else {

            echo "Invalid file type";
        }
    } else {

        echo "no file to upload";
    }

?>

Then I changed my code to work this way.

NSString *urlString = [NSString stringWithFormat:@"https://%@/mamobile/uploadPicture.php", [[NSUserDefaults standardUserDefaults] stringForKey:@"serviceIPAddress"]];
    AFHTTPSessionManager *imageSession = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:urlString]];
    imageSession.responseSerializer = [MSJSONResponseSerializerWithData serializer];
    [imageSession.requestSerializer setAuthorizationHeaderFieldWithUsername:@"fake username" password:@"fake password"];
    [imageSession.securityPolicy setAllowInvalidCertificates:YES];

    [imageSession POST:@"" parameters:nil constructingBodyWithBlock:^(id <AFMultipartFormData>formData) {

        NSData *imageData = UIImageJPEGRepresentation(image, 90);

        NSString *fileName = [NSString stringWithFormat:@"%@.jpg", persistentID];

        NSLog(@"uploading image '%@' with size = %@",fileName,[NSByteCountFormatter stringFromByteCount:imageData.length countStyle:NSByteCountFormatterCountStyleFile]);

        [formData appendPartWithFileData:imageData name:@"file" fileName:fileName mimeType:@"image/jpg"];

    } success:^(NSURLSessionDataTask * task, id responderData) {
        NSLog(@"Success: %@", responderData);
        self.itemImageBlock(YES);

    } failure:^(NSURLSessionDataTask * task, NSError * error) {
        NSLog(@"Error: %@",error);
        self.itemImageBlock(NO);

    }];

But I still get the same timeout message. So it has nothing to do with the slim php framework.

Hackmodford
  • 3,901
  • 4
  • 35
  • 78
  • Is the success block, the failure block, or neither called? If one of the blocks is called, set a breakpoint in it and type `po task`, and either `po responderData` or `po error` in the debugger. If neither of the blocks is called, open up AFURLSessionManager.m and place breakpoints in both `dataTaskWithRequest: completionHandler:` and the version of `URLSession: task: didCompleteWithError:` in the `AFURLSessionManagerTaskDelegate` implementation. Step through those methods and make sure the behavior is what you'd expect. – Aaron Brager Oct 18 '13 at 17:49
  • the failure block is called and it simply says it timedout. – Hackmodford Oct 18 '13 at 18:06
  • Can you post the actual error? – Aaron Brager Oct 21 '13 at 06:50

2 Answers2

0

The error you are getting is : The request timed out.

This means, the image you are uploading from mobile to PHP script is taking longer than the max setting for script execution time config on your PHP.

To fix this, you can add this at the beginning of your PHP script:

<?php 

// Allow script to run longer
set_time_limit(600); // in seconds, set it to 0 to run forever until completion

// Proceed with upload
if (!empty($_FILES)) {
    ...
}
Latheesan
  • 23,247
  • 32
  • 107
  • 201
  • I'll try it, but I send the same image to my old script and it works pretty fast. Using NSMutableRequest and it works fine. (granted the php script is slightly different) – Hackmodford Oct 23 '13 at 13:09
0

https://github.com/AFNetworking/AFNetworking/issues/1510#issuecomment-29687300

There is a problem I also similar. Solution is to add from the following code.

[formData appendPartWithFormData:[[NSNumber numberWithInt:imageData.length].stringValue dataUsingEncoding:NSUTF8StringEncoding] name:@"filelength"];
niceilm
  • 114
  • 1
  • 4