POST JSON data into existing object POST JSON data into existing object ios ios

POST JSON data into existing object


You do this wrong:

NSMutableDictionary *params = [[NSMutableDictionary alloc] init];[[[params objectForKey:@"zoneresponse"] objectForKey:@"tasks"] setValue:@"HelloWorld" forKey:@"datafield1"];

Your params is empty dictionary and no object will be returned with [params objectForKey:@"zoneresponse"].

Try this:

NSMutableDictionary *params = [NSMutableDictionary new];params[@"zoneresponse"] = @{@"tasks": @{@"datafield1": @"HelloWorld"}};

This will work but object for key @"tasks" will be immutable. To add another objects to tasks dictionary we need to make it mutable:

NSMutableDictionary *params = [NSMutableDictionary new];NSMutableDictionary *tasks = [NSMutableDictionary new];params[@"zoneresponse"] = @{@"tasks": tasks};params[@"zoneresponse"][@"tasks"][@"datafield1"] = @"HelloWorld";

or

NSMutableDictionary *params = [NSMutableDictionary new];    params[@"zoneresponse"] = @{@"tasks": [@{@"datafield1": @"HelloWorld"} mutableCopy]};

Then you can add another objects to tasks:

params[@"zoneresponse"][@"tasks"][@"datafield2"] = @"HelloWorld2";params[@"zoneresponse"][@"tasks"][@"datafield3"] = @"HelloWorld3";

I think my answer will bring some clarity to operations with dictionaries for you.


Architectural context of your approach to sending JSON data to a servers database:

You are using an old method (since 03') of making a HTTP POST request to get your lovely JSON data in to the servers database. It is still functional and not deprecated and ultimately an acceptable approach. Typically how this approach works is you set up and fire a NSURLRequest with a NSURLConnection, the ViewController or object that fired the request typically implements the NSURLConnection protocol so you have a callback method that receives the NSURLRequests associated response as you've done. Theres also some NSURLCaching and NSHTTPCookStorage available to avoid redundancy and speed up the whole thing.

There is a new way (since 13'):

NSURLConnections successor is NSURLSession. Since Vladimir Kravchenko's answer focusses on forming the NSDictionary to be sent as a parameter who showed that you need to use a NSMutableDictionary instead of a static NSDictionary which can't be edited after it's init'ed. I'll focus on the networking approach surrounding your question though in order to be helpful.

/*The advantage of this code is it doesn't require implementing aprotocol or multiple callbacks.It's self contained, uses a more modern framework, less codeand can be just thrown in to the viewDidAppearBasically - theres less faffing about while being a little easier to understand.*/NSError *requestError;// session configNSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];// setup requestNSURL *url = [NSURL URLWithString:testingURL];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy                                                   timeoutInterval:60.0];[request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];[request setHTTPMethod:@"POST"];// setup request parameters, Vladimir Kravchenko's use of literals seems fine and I've taken his codeNSDictionary *params = @{@"zoneresponse" : @{@"tasks" : [@{@"datafield1" : @"HelloWorld"} mutableCopy]}};params[@"zoneresponse"][@"tasks"][@"datafield2"] = @"HelloWorld2";params[@"zoneresponse"][@"tasks"][@"datafield3"] = @"HelloWorld3";// encode parametersNSData *postData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&requestError];[request setHTTPBody:postData];// fire request and handle responseNSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:    ^(NSData *data, NSURLResponse *response, NSError *error) {    NSError *responseError;    // parse response    NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data                                                                 options:NSJSONReadingAllowFragments                                                                   error:&responseError];    // handle response data    if (responseError){        NSLog(@"Error %@", responseError)    }else{        if (responseDict){            NSLog(@"Response %@", responseDict);        }    }}];[postDataTask resume];

Further Reading

The always wonderful Mattt Thompson has written about the transition from NSURLConnection to NSURLSession here:objc.io

You can find another similar Stack Overflow Questions here:Stack Overflow

If you would like a networking library that makes these issues a little easier check out Mattt Thompsons AFNetworking which can be found here:GitHub

Further analysis on NSURLConnection versus NSURLSession can be found here:Ray Wenderlich