AFNetworking 2 - Image upload - Request failed: un

2019-07-07 05:22发布

问题:

I know this question was answered multiple times, but I tried all the answers with no luck. I don't think that I do something fundamentally wrong but something goes definitely wrong here.

I use the following code to upload PNG files to tinypng.com. As far as I can see the upload itself works, but I receive the error message: Request failed: unsupported media type (415)

The images I use are loaded as JPEG, then resized and transformed to PNG format. The saved files are fine. Now I want send them to the TinyPNG API before I save them to disc.

If anyone has an idea whats wrong or has experience with that service, please let me know. Thanks in advance!

Detailed error message

Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: unsupported media type (415)" 
UserInfo=0x6000000e4900 {
    com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x600000220200> { URL: https://api.tinypng.com/shrink } 
    { 
        status code: 415, headers {
            Connection = "keep-alive";
            "Content-Length" = 77;
            "Content-Type" = "application/json; charset=utf-8";
            Date = "Tue, 16 Dec 2014 20:24:16 GMT";
            Server = "Apache/2";
            "Strict-Transport-Security" = "max-age=31536000";
            "X-Powered-By" = "Voormedia (voormedia.com/jobs)";
        } 
    }, 
    NSErrorFailingURLKey=https://api.tinypng.com/shrink,
    com.alamofire.serialization.response.error.data=<7b226572 726f7222 3a224261 64536967 6e617475 
    7265222c 226d6573 73616765 223a2244 6f657320 6e6f7420 61707065 61722074 6f206265 20612050 
    4e47206f 72204a50 45472066 696c6522 7d>, 
    NSLocalizedDescription=Request failed: unsupported media type (415)
}

The code I use

-(void) uploadImage:(NSImage *)image {

    AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:TINY_PNG_URL]];

    CGImageRef cgRef = [image CGImageForProposedRect:NULL
                                             context:nil
                                               hints:nil];
    NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
    [newRep setSize:[image size]];   // if you want the same resolution
    NSData *imageData = [newRep representationUsingType:NSPNGFileType properties:nil];

    NSDictionary *parameters = @{@"username": USERNAME, @"password" : PASSWORD};

    AFHTTPRequestOperation *operation = [manager POST:@"" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

        //append image
        [formData appendPartWithFileData:imageData
                                    name:@"filename"
                                fileName:@"photo.png"
                                mimeType:@"image/png"];

    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"Success: %@ ***** %@", operation.responseString, responseObject);

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@ ***** %@", operation.responseString, error);
    }];

    [operation start];
} 

回答1:

With the support of Mattijs from TinyPNG I've got it working! Thanks Mattijs!

The problem was, that the TinyPNG API expects the request body to only be the image data, which isn't the case with the multipart form data body I used in my original code.

My working solution is:

-(void) uploadImage:(NSImage *)image {

    NSData *imageData = [self PNGRepresentationOfImage:image];

    NSURL *url = [NSURL URLWithString:TINY_PNG_URL];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:imageData];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"image/png" forHTTPHeaderField:@"Content-Type"];

    NSString *authStr = [NSString stringWithFormat:@"%@:%@", USERNAME, PASSWORD];
    NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
    NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]];
    [request setValue:authValue forHTTPHeaderField:@"Authorization"];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id result) {
        NSLog(@"Success: %@ ***** %@", operation.responseString, result);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@ ***** %@", operation.responseString, error);
    }];
    [operation start];
}