Chris Wagner Chris Wagner - 23 days ago 15
iOS Question

AFNetworking base64 parameter, characters being escaped by NSJSONSerialization

I am attempting to submit an image to CardShark's API using AFNetworking.

NSData *imageData = UIImageJPEGRepresentation(cardImage, 1.0);
NSDictionary *parameters = @{@"front" : [imageData base64EncodedStringWithSeparateLines:NO]};

NSString *path = [NSString stringWithFormat:@"cardShark?webhookUrl=%@&apiKey=%@", kCardSharkWebHookURLEncodedString, kCardSharkAPIKey];

[self postPath:path parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
completion(responseObject, nil);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
completion(nil, error);
}];


I've tried all combinations of the base64 string.

base64EncodedStringWithSeparateLines:YES
base64EncodedStringWithSeparateLines:NO
base64EncodedString`


To no avail, after inspecting the
HTTPBody
on the request that is generated I am seeing that things are being escaped.

The raw base64 starts with

/9j/4AAQSkZJRgABAQAAAQABAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAAB
AAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAEOKAD
AAQAAAABAAACrAAAAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB


But once it's gone through AFNetworking and presumably NSJSONSerialization it is being posted as

\/9j\/4AAQSkZJRgABAQAAAQABAAD\/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAEOKADAAQAAAABAAACrAAAAAD\/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH\/


As you can see the
/
are being escaped. How do I prevent the escaping? Passing the exact JSON body to the API via another tool (a la, curl) causes the API to produce an error. So what's the best approach here?

Answer

It turns out that this was more of the fault of the API. AFNetworking has the following code that sets the Content-Type header with charset=utf-8.

case AFJSONParameterEncoding:;
                    [request setValue:[NSString stringWithFormat:@"application/json; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
                    [request setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error]];
                    break;

For whatever reason that is beyond my understanding, their API did not support the charset attribute on the header.

With that said, they were fast to fix this issue and it is now working with no modification to the code shown above.