2

I'm having a problem using AFNetworking with Parse.com. I'm trying to POST data to the db with no luck. I'm not too familiar with networking stuff and so I'm using this as a learning exercise.

I've gotten the GET command to work so I know that the db is set up correctly and working but POSTing is another matter. I'm using AFNetworking 2.2.0 to POST a simple test string to the parse backend.

Here is the code I have for the GET command which works:

-(void)getParseData{

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

[manager.requestSerializer setValue:kSDFParseAPIApplicationId forHTTPHeaderField:@"X-Parse-Application-Id"];
[manager.requestSerializer setValue:kSDFParseAPIKey forHTTPHeaderField:@"X-Parse-REST-API-Key"];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

[manager GET:@"https://api.parse.com/1/classes/some_data/" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);

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

}

and here is the code I have so far for the POSt command, which is't working:

-(void)postParseData{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

[manager.requestSerializer setValue:kSDFParseAPIApplicationId forHTTPHeaderField:@"X-Parse-Application-Id"];
[manager.requestSerializer setValue:kSDFParseAPIKey forHTTPHeaderField:@"X-Parse-REST-API-Key"];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

manager.responseSerializer = [[AFJSONResponseSerializer serializer]init];

NSDictionary *params = @{@"test_string" : @"NameTest"};

[manager POST:@"https://api.parse.com/1/classes/warm_data/" parameters: params  success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"POST data JSON returned: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];
}

I know there is a custom parse.com API for iOS for this exact purpose but I want to use AFNetworking to learn more and improve. I've tried several different things I'v found on the net and specifically from stack overflow but noting yielded a result. Here is the error message returned from the AFHTTPRequestOperation failure block:

 2014-03-24 11:42:07.894 testApp[3222:60b] Error: Error Domain=AFNetworkingErrorDomain Code=-1011 "Request failed: bad request (400)" UserInfo=0xfe0f400 {NSErrorFailingURLKey=https://api.parse.com/1/classes/some_data/, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x14780070> { URL: api.parse.com/1/classes/some_data/ } { status code: 400, headers {
    "Access-Control-Allow-Origin" = "*";
    "Access-Control-Request-Method" = "*";
    "Cache-Control" = "no-cache";
    Connection = "keep-alive";
    "Content-Length" = 130;
    "Content-Type" = "application/json; charset=utf-8";
    Date = "Mon, 24 Mar 2014 11:42:07 GMT";
    Server = "nginx/1.4.2";
    "Set-Cookie" = "_parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlYWQyNmFhMTA3ZTJkZjljYjA3MjZkZTA1MGQzNWIzNGE%3D--f7812e190b5812d8bba91aea2b12d51412bf84ce; domain=.parse.com; path=/; expires=Wed, 23-Apr-2014 11:42:07 GMT; secure; HttpOnly";
    Status = "400 Bad Request";
    "X-Runtime" = "0.049574";
    "X-UA-Compatible" = "IE=Edge,chrome=1";
} }, NSLocalizedDescription=Request failed: bad request (400)}

Any and all help is appreciated. If I've forgotten any thing or omitted something needed to fix the problem just let me know and I'll add what I can.

Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
CrazyedM
  • 87
  • 1
  • 9
  • You shouldn't have a trailing slash on your URL paths when posting. – Wain Mar 24 '14 at 12:09
  • I just removed the trailing slash from the URL path so its now : https://api.parse.com/1/classes/warm_data but its still the same error message unfortunately. – CrazyedM Mar 24 '14 at 12:21
  • 1
    Does your `warm_data` class already exist in the data browser? – Wain Mar 24 '14 at 12:31
  • @Wain Yes, it does. I tried to add a picture of the data browser from Parse.com to show you but I'v not got a high enough score to post pictures yet. – CrazyedM Mar 24 '14 at 12:48
  • Are you sure your keys are correct? Does using CURL work for the same request? – Wain Mar 24 '14 at 12:54
  • @wain Yes, tried cURL and it works, keys are correct. I can POST via curl and looking at the returned error code: "400 Bad Request" I think the problem may be what I'm sending parameter wise in the POST request. NSDictionary *params = @{@"test_string" : @"NameTest"}; may not be in the correct format but the AFNetworking docs do show a JSON POST request with the supplied parameters in a NSDictionary format. AFNetworking Docs:[link](http://cocoadocs.org/docsets/AFNetworking/2.2.1/#post-url-form-encoded-request) – CrazyedM Mar 24 '14 at 19:45
  • Did you set the request serializer for JSON? – Wain Mar 24 '14 at 19:49
  • @Wain No there was no response serializer but I added one: manager.responseSerializer = [AFJSONResponseSerializer serializer]; however it made no difference, still getting a 400 error. (I've added the serializer code to the original question now) – CrazyedM Mar 25 '14 at 00:36
  • I said request serializer. Use Charles to check what is actually being sent. – Wain Mar 25 '14 at 08:26

1 Answers1

2

After trying suggestions from helpful commenters and lots more reading and just trying stuff I got POST working with AFNetworking! The working code is as follows:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

manager.requestSerializer = [AFJSONRequestSerializer serializer];

[manager.requestSerializer setValue:kSDFParseAPIApplicationId forHTTPHeaderField:@"X-Parse-Application-Id"];
[manager.requestSerializer setValue:kSDFParseAPIKey forHTTPHeaderField:@"X-Parse-REST-API-Key"];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

NSDictionary *dic2 = @{@"test_number": @1234};

[manager POST:@"https://api.parse.com/1/classes/warm_data" parameters: dic2
      success:^(AFHTTPRequestOperation *operation, id responseObject) {
          NSLog(@"POST data JSON returned: %@", responseObject);
      }
      failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          NSLog(@"Error: %@", error);
      }
 ]; 

This is the same code as before which is weird. I was looking through the AFNetworking docs and other posts talking about AFnetworking including some StackOverflow questions here and came across the

.securityPolicy.allowInvalidCertificates = YES;

part of the AFHTTPRequestOperationManager. I added this line to below the manager declaration:

manager.securityPolicy.allowInvalidCertificates = YES;

And suddenly it started working! I then set the manager.securityPolicy.allowInvalidCertificates to NO and it still worked?!?! then I removed the line complete and it keeps working, posting stuff to Parse for me. Very weird. I have no explanation how this fixed it, maybe it forced the parse servers to allow it when the cert was removed, again I have no idea. I'd love to know what changed but for now I'm going to continue on and build the rest of the app. If anyone has any theories I'd love to hear them!

Thanks again to all the commenters who took the time to suggest stuff, I appreciate it.

Community
  • 1
  • 1
CrazyedM
  • 87
  • 1
  • 9