POST JSON数据到现有的对象

我从格式如下的URL中检索JSON数据:

{"zoneresponse": {"tasks": [{"datafield1":"datafor1", "datafield2":"datafor2", "datafield3":"datafor3",... }] }} 

我无法控制这个结构,因为它来自一个私有的API。

如何在现有对象的选定数据字段中插入数据?

我试过这个:

 self.responseData = [NSMutableData data]; //testingURL is the api address to the specific object in tasks NSURL *url = [NSURL URLWithString:testingURL]; NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; [[[params objectForKey:@"zoneresponse"] objectForKey:@"tasks"] setValue:@"HelloWorld" forKey:@"datafield1"]; //HAVE TRIED setObject: @"" objectForKey: @"" as well //*****PARAMS IS EMPTY WHEN PRINTED IN NSLog WHICH IS PART OF THE ISSUE - SETTING VALUE DOES NOT WORK NSError * error = nil; NSLog(@"Params is %@", params); NSData *requestdata = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error]; NSMutableURLRequest *request; request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; [request setValue:[NSString stringWithFormat:@"%d", [requestdata length]] forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:requestdata]; NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; if(conn) { NSLog(@"Connection Successful, connection is: %@", conn); } else { NSLog(@"Connection could not be made"); } 

正在build立连接,但打印时字典参数是空的(setValue不显示),并且没有在我select的字段中input任何数据。

我已经检查了这些链接,但没有任何解释是否将插入到正确的字段,并暗示它将创build一个新的对象,而不是更新现有的。

如何通过json API来更新服务器数据库上的数据?

如何使用NSURLRequest发送Http请求中的json数据

委托方法

 //any time a piece of data is received we will append it to the responseData object - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.responseData appendData:data]; NSError *jsonError; id responseDict = [NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingAllowFragments error:&jsonError]; NSLog(@"Did Receive data %@", responseDict); } //if there is some sort of error, you can print the error or put in some other handling here, possibly even try again but you will risk an infinite loop then unless you impose some sort of limit - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { // Clear the activeDownload property to allow later attempts self.responseData = nil; NSLog(@"Did NOT receive data "); } //connection has finished, the requestData object should contain the entirety of the response at this point - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSError *jsonError; id responseDict = [NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingAllowFragments error:&jsonError]; if(responseDict) { NSLog(@"%@", responseDict); } else { NSLog(@"%@", [jsonError description]); } //clear out our response buffer for future requests self.responseData = nil; } 

这里的第一个方法表明,数据接收“没有接收数据(空)”,没有连接错误,但是最后的方法打印错误消息“JSON文本没有开始数组或对象和选项,以允许片段没有设置。“,这是可以理解的,因为没有数据或对象被发送。

如何将数据插入到现有对象的选定字段中?

你做错了:

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

你的params是空的字典,没有对象将返回[params objectForKey:@"zoneresponse"]

尝试这个:

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

这将工作,但对象的关键@"tasks"将是不可改变的。 要添加另一个对象到tasks字典,我们需要使其变为可变的:

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

要么

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

然后你可以添加另一个对象到tasks

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

我想我的答案会为你的字典操作带来一些清晰。

将JSON数据发送到服务器数据库的方法的架构上下文:

你正在使用一个旧的方法(03'以来)做一个HTTP POST请求,让你可爱的JSON数据到服务器数据库。 它仍然是function性的,不被弃用,最终是一个可接受的方法。 通常情况下,这种方法的工作方式是使用NSURLConnection设置并激发一个NSURLRequest,触发请求的ViewController或者对象通常实现NSURLConnection协议,所以你有一个callback方法来接收NSURLRequests相关的响应。 也有一些NSURLCaching和NSHTTPCookStorage可用来避免冗余和加速整个事情。

有一个新的方法(从13'):

NSURLConnections后继是NSURLSession。 由于弗拉基米尔克拉夫琴科的答案集中在形成NSDictionary作为参数发送,表明你需要使用一个NSMutableDictionary而不是一个静态的NSDictionary,它不能被编辑后,它被初始化。 我将专注于围绕您的问题的networking方法,以便有所帮助。

 /* The advantage of this code is it doesn't require implementing a protocol or multiple callbacks. It's self contained, uses a more modern framework, less code and can be just thrown in to the viewDidAppear Basically - theres less faffing about while being a little easier to understand. */ NSError *requestError; // session config NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; // setup request NSURL *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 code NSDictionary *params = @{@"zoneresponse" : @{@"tasks" : [@{@"datafield1" : @"HelloWorld"} mutableCopy]}}; params[@"zoneresponse"][@"tasks"][@"datafield2"] = @"HelloWorld2"; params[@"zoneresponse"][@"tasks"][@"datafield3"] = @"HelloWorld3"; // encode parameters NSData *postData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&requestError]; [request setHTTPBody:postData]; // fire request and handle response NSURLSessionDataTask *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]; 

进一步阅读

总是美妙的Mattt Thompson写了关于从NSURLConnection到NSURLSession的转换: objc.io

你可以在这里find另一个类似的Stack Overflow Questions: Stack Overflow

如果你想要一个networking库,使这些问题更容易检查Mattt Thompsons AFNetworking可以在这里find: GitHub

NSURLConnection与NSURLSession的进一步分析可以在这里find: Ray Wenderlich