0
votes

I keep receiving the following error message: 2013-01-22 01:44:43.091 Section3App2[16625:6703] -[__NSCFArray length]: unrecognized selector sent to instance 0x23a48780 after submitting my AFNetworking Request. The idea behind the request is that we are sending a post request to a REST API with a JSON Request Body via POST. I have been fiddling with this all day and can't seem to figure out whats causing the problem.

CODE

NSString *string = @"[{\"code\": \"105N14560\"}]";
    NSString * jsonString = string;
    NSData * data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSError * error = nil;
    id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        [request setHTTPBody:json];
       // [request setValue:[NSString stringWithFormat:@"%d", string.length] forHTTPHeaderField:@"Content-Length"];
        NSLog(@"request body:%@", request.HTTPBody);
       // NSLog(@"json: %@",json);
//    if (!json) {
//        // handle error
//        NSLog(@"fail");
//    }
        AFJSONRequestOperation *operation2 = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
            NSLog(@"JSON: %@", JSON);
        } failure:nil];
        [operation2 start];

That code successfully creates the request body but when it tries to run the block it throws the error and I'm completely stumped. All help would be greatly appreciated.

1
Notice that you are passing json as the argument to setHTTPBody:. This should be an NSData object per the docs, but you've passed it an NSArray by deserializing te JSON string you constructed. Just pass data as your argument, you don't need to deserialize the JSON prior to posting it.Carl Veazey

1 Answers

3
votes

Never try to build the JSON string yourself like you're doing in the first line. Use NSJSONSerialization to convert from a JSON-compatible Obj-C data structure (like NSDictionary or NSArray) directly to an NSData object to use as the body of the request. For example:

NSDictionary *JSON = [NSDictionary dictionaryWithObject:@"105N14560" forKey:@"code"];
id JSONData = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:error];

You should use the resulting JSONData object for both the HTTPBody of the request as well as the content-length of the request. Here is a complete example:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; // URL = wherever the request should be sent to 

[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"content-type"];

id JSONData = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:error];
if (JSONData) {
    [request setValue:[NSString stringWithFormat:@"%d",[(NSData *)JSONData length]] forHTTPHeaderField:@"content-length"];
    [request setHTTPBody:JSONData];
}

This just creates the request. The rest of it is straightforward using AFNetworking, where using AFJSONRequestOperation you just pass in the request as you've already done.