4

I'm trying to send an audio file to a PHP server. Here is the Objective-C code:

NSData *data = [NSData dataWithContentsOfFile:filePath];

NSLog(@"File Size: %i",[data length]);

//set up request
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"POST"];

//required xtra info
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];

//body of the post
NSMutableData *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"thefile\"; filename=\"recording\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:data];
[postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:postbody];
apiConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

And here is the PHP code:

if (is_uploaded_file($_FILES['thefile']['tmp_name'])) {
    echo "FILE NAME: ".$_FILES['thefile']['name'];
} else {
    echo "Nothing";
}

The File Size varies depending on the length of audio being recorded, but there is data.

I'm getting a response of "Nothing".

Chris
  • 495
  • 1
  • 8
  • 19

3 Answers3

7

To debug: on the PHP side, try:

$file = $_POST['name'];
echo $file

Try the following code segment in place of your current code. Change the url (www.yourWebAddress.com) and script name to appropriate values for your problem.

NSData *data = [NSData dataWithContentsOfFile:filePath];
NSMutableString *urlString = [[NSMutableString alloc] initWithFormat:@"name=thefile&&filename=recording"];
[urlString appendFormat:@"%@", data];
NSData *postData = [urlString dataUsingEncoding:NSASCIIStringEncoding 
                                   allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
NSString *baseurl = @"https://www.yourWebAddress.com/yourServerScript.php"; 

NSURL *url = [NSURL URLWithString:baseurl];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setHTTPMethod: @"POST"];
[urlRequest setValue:postLength forHTTPHeaderField:@"Content-Length"];
[urlRequest setValue:@"application/x-www-form-urlencoded" 
          forHTTPHeaderField:@"Content-Type"];
[urlRequest setHTTPBody:postData];

NSURLConnection *connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
[connection start];

NSLog(@"Started!");

On the server end, I have the following code:

<?php

    $name  = $_POST['name'];
    $filename  = $_POST['filename'];
    echo "Name = '" . $name . "', filename = '" . $filename . "'.";

    error_log ( "Name = '" . $name . "', filename = '" . $filename . "'." );

?>

I received the following output:

[23-May-2012 11:56:18] Name = 'thefile', filename = 'recording'.

I don't know why it is not working for you. You must have a missing step. Try commenting out the two lines in the url POST code above that references 'data' to see that you can get at the least the plain text for name and filename to your server end.

Good luck!

Sunny
  • 1,464
  • 14
  • 26
  • 1
    Sunny, the file name is blank. – Chris May 22 '12 at 23:41
  • Ok, I've updated my answer. Try my code to see how it works for you. – Sunny May 23 '12 at 00:12
  • Oops. I have fixed the typo from cutting and pasting for: "NSMutableString *urlString = [[NSMutableString alloc] initWithFormat:@"name=thefile&&filename=recording"];" – Sunny May 23 '12 at 00:13
  • Also blank. To make sure it's reaching the server, I added FILE NAME: to the echo. – Chris May 23 '12 at 00:46
  • You said "I added FILE NAME:" No, don't add FILE NAME:. This is case sensitive. you should be echoing "$_POST['name']" and "$_POST['filename']" in your PHP script. My code should not be producing blanks for these values. – Sunny May 23 '12 at 01:32
  • $file = $_POST['name']; echo "FILE NAME: ".$file; – Chris May 23 '12 at 16:06
  • I added the FILE NAME to see if it was echoing anything. Without FILE NAME: in there, the response was empty. – Chris May 23 '12 at 16:10
  • Look, the code works. I don't know why this is not working for you. I went ahead and tested my code above on it's own standalone project and got the output I indicate in latest edit of my answer. You need to make sure you are not introducing any bugs on your own. The code works. – Sunny May 23 '12 at 18:04
  • I know the code should work. I've been able to send files before, but for some reason it's stopped. I've tried two different sites. The only thing I can think of is the server, which hosts both sites isn't accepting them. – Chris May 24 '12 at 16:04
  • I have the PHP part setup exactly the way you show above. The url is http://www.checklyst.com/receiveFile.php could you try sending to that? If you get an empty name and filename then I'll know it's a server issue. The URL is not HTTPS but HTTP – Chris May 24 '12 at 16:09
  • I am afraid that I cannot test your link right. However, if your site does not support https, then make sure that you change the baseURL from "NSString *baseurl = @"https://..";" to "NSString *baseurl = @"http://...";" Good luck! – Sunny May 24 '12 at 17:14
  • 1
    I tested your link moments ago. I got back "Name = 'thefile', filename = 'recording'." on my app NSURLConnection -(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data delegate. However, if your site does not support https, then make sure that you change the baseURL from "NSString *baseurl = @"https://..";" to "NSString *baseurl = @"http://...";" Also, make sure you declared that your viewController implements NSURLConnectionDelegate. Good luck! – Sunny May 24 '12 at 17:22
  • Thanks! So the good news is it's in my Objective-C code. Will go ahead and mark your answer as accepted. – Chris May 24 '12 at 17:56
1

Try encoding your binary data before you send it over the pipe (and then decode when it gets to the other end). See this SO thread for ideas for Base64 encoding code.

Community
  • 1
  • 1
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
0

In swift you can post like this..

    func wsPostData(apiString: String, jsonData: String) -> Void
    {
         //apiString means base URL
        let postData = jsonData.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)
        let postLenth = "\(UInt((postData?.length)!))"
        let request = NSMutableURLRequest()
        request.URL = NSURL(string: apiString)
        request.HTTPMethod = "POST"
        request.setValue(postLenth, forHTTPHeaderField: "Content-Lenth")
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.HTTPBody = postData
        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse?, data: NSData?, error:NSError?) in

            print("response\(response)")
            var dict:NSDictionary!
            do {
                dict = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [String: AnyObject]
                print(" responce data is \(dict)")
            }
            catch let error as NSError
            {
                print("Something went wrong\(error)")
            }

        }
    }
kalpesh
  • 1,285
  • 1
  • 17
  • 30