Bild von iOS App auf PHP hochladen - Kann es nicht ganz richtig machen - Was fehle ich?

Erstens weiß ich, dass diese Frage tausendmal gestellt wurde. Ich frage noch einmal, weil ich die Lösungen in den anderen Beispielen ausprobiert habe und sie für mich nicht funktionieren und ich nicht weiß, warum. Jeder scheint einen etwas anderen Ansatz zu haben.

NSData *imageData =  UIImagePNGRepresentation(form.image);
NSURL *url = [NSURL URLWithString:@"myscript.php"];
NSMutableString *postParams = [[NSMutableString alloc] initWithFormat:@"&image=%@", imageData]];

NSData *postData = [postParams dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [[NSString alloc] initWithFormat:@"%d", [postData length]];

NSMutableURLRequest *connectRequest = [[NSMutableURLRequest alloc] init];
[connectRequest setURL:url];
[connectRequest setHTTPMethod:@"POST"];
[connectRequest setValue:postLength forHTTPHeaderField:@"Content-Length"];
[connectRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
//[connectRequest setValue:@"image/png" forHTTPHeaderField:@"Content-Type"];
[connectRequest setHTTPBody:postData];

NSData *receivedData;
NSDictionary *jsonData;

NSURLConnection *connectConnection = [[NSURLConnection alloc] initWithRequest:connectRequest delegate:self];

NSError *error = nil;

if (!connectConnection) {
    receivedData = nil;
    NSLog(@"The connection failed!");
} else {
    NSLog(@"Connected!");
    receivedData = [NSURLConnection sendSynchronousRequest:connectRequest returningResponse:NULL error:&error];
}

if (!receivedData) {
    NSLog(@"Data fetch failed: %@", [error localizedDescription]);
} else {
    NSLog(@"The data is %lu bytes", (unsigned long)[receivedData length]);
    NSLog(@"%@", receivedData);

    if (NSClassFromString(@"NSJSONSerialization")) {
        id object = [NSJSONSerialization JSONObjectWithData:receivedData options:0 error:&error];

        if (!object) {
            NSLog(@"JSON Serialization failed: %@", [error localizedDescription]);
        }

        if ([object isKindOfClass:[NSDictionary class]]) {
            jsonData = object;
            NSLog(@"json data: %@", jsonData);
        }
    }
}

Im Moment übergebe ich die NSData in den postParams und benutze dieses PHP-Skript:

if (isset($_POST['image']) && !empty($_POST['image'])) {

     if (file_put_contents('images/test.png', $_POST['image'])) {
           echo '{"saved":"YES"}'; die();
     } else {
           echo '{"saved":"NO"}'; die();     
     }
}

Dies speichert die Daten in einer Datei, aber ich kann sie nicht öffnen, da sie beschädigt sind oder ähnliches. Dies war so ziemlich eine letzte Anstrengung, und ich hatte nicht wirklich erwartet, dass es so funktioniert, aber es ist so nah, wie ich es bisher richtig gemacht habe.

Ich habe versucht, verschiedene Content-Header- / Boundary- / $ _FILES- / Enctype-Content-Type-Methoden zu verwenden, aber ich kann nicht einmal erreichen, dass es so richtig an das Skript gesendet wird.

Im Übrigen sende ich nicht nur die Bilddaten, sondern auch andere Werte in den postParams, die nur Strings, Ints usw. sind.

Hat jemand irgendwelche Vorschläge oder kennt jemand gute Quellen dafür?

Vielen Dank für jede Hilfe angeboten.

Aktueller Stand nach folgenden Ratschlägen in den Antworten unten (auch weitere Informationen aus anderen Programmteilen):

Erstaufnahme des Bildes:

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [self.view endEditing:YES];

    __unused form *form = self.form;

    form.signature = self.signatureDrawView.bp;

    UIGraphicsBeginImageContext(self.signatureDrawView.bounds.size);
    [self.signatureDrawView.layer renderInContext:UIGraphicsGetCurrentContext()];
    campaignForm.signatureImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

Dabei ist signatureDrawView ein UIView und form.signature ein UIBezierpfad.

dann...

NSData *sigImage =  UIImagePNGRepresentation(campaignForm.signatureImage);

die an die folgende Funktion übergeben wird:

- (void)uploadImage:(NSData *)imageData
{
    NSMutableURLRequest *request;
    NSString *urlString = @"https://.../upload.php";
    NSString *filename = @"uploadTest";
    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 *postbody = [NSMutableData data];
    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@.png\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[NSData dataWithData:imageData]];
    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:postbody];

    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *returnString;
    returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
    NSLog(@"%@", returnString);
}

upload.php sieht so aus:

    if ($_FILES["file"]["error"] > 0) {
        echo '{"file":"'.$_FILES['file']['error'].'"}';
        die();
    } else {
        $size = $_FILES["file"]["size"] / 1024;
        $upload_array = array(
                    "Upload"=>$_FILES["file"]["name"],
                    "Type"=>$_FILES["file"]["type"],
                    "Size"=>$size,
                    "Stored in"=>$_FILES["file"]["tmp_name"]
                    );
        //echo json_encode($upload_array);
        if (move_uploaded_file($_FILES["file"]["tmp_name"], "signatures/" . $_FILES["file"]["name"])) {
            echo '{"success":"YES"}';
            die();  
        } else { 
            echo '{"success":"NO"}';
            die();  
        }
        die();
    }

Dadurch erhalte ich die Ausgabe {success: NO} und der Speicherauszug $ upload_array zeigt Nullwerte an.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage