首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将JSON数据发布到现有对象中

将JSON数据发布到现有对象中
EN

Stack Overflow用户
提问于 2015-04-16 16:28:05
回答 2查看 1.9K关注 0票数 17

我从一个URL中检索JSON数据,该URL的格式如下:

代码语言:javascript
复制
{"zoneresponse":
{"tasks":
 [{"datafield1":"datafor1", 
   "datafield2":"datafor2", 
   "datafield3":"datafor3",...
 }]
}}

我无法控制该结构,因为它来自私有API。

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

我已经尝试过了:

代码语言:javascript
复制
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");
}

正在建立连接,但打印时字典参数为空( setValue未显示),并且没有在我选择的字段中输入任何数据。

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

How to update data on server db through json api?

How to send json data in the Http request using NSURLRequest

委托方法

代码语言:javascript
复制
//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;
}

这里的第一个方法说明接收数据时使用了"Did Receive data (null)",连接没有错误,但是最后一个方法输出错误消息"JSON text not start with array or object and option to allow fragments not set.",这是可以理解的,因为没有发送数据或对象。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-22 17:47:59

您这样做是错误的:

代码语言:javascript
复制
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
[[[params objectForKey:@"zoneresponse"] objectForKey:@"tasks"] setValue:@"HelloWorld" forKey:@"datafield1"];

您的params为空字典,[params objectForKey:@"zoneresponse"]将不会返回任何对象。

试试这个:

代码语言:javascript
复制
NSMutableDictionary *params = [NSMutableDictionary new];
params[@"zoneresponse"] = @{@"tasks": @{@"datafield1": @"HelloWorld"}};

这将会起作用,但密钥@"tasks"的对象将是不可变的。要将另一个对象添加到tasks字典中,我们需要使其成为可变的:

代码语言:javascript
复制
NSMutableDictionary *params = [NSMutableDictionary new];
NSMutableDictionary *tasks = [NSMutableDictionary new];
params[@"zoneresponse"] = @{@"tasks": tasks};
params[@"zoneresponse"][@"tasks"][@"datafield1"] = @"HelloWorld";

代码语言:javascript
复制
NSMutableDictionary *params = [NSMutableDictionary new];    
params[@"zoneresponse"] = @{@"tasks": [@{@"datafield1": @"HelloWorld"} mutableCopy]};

然后,您可以将其他对象添加到tasks

代码语言:javascript
复制
params[@"zoneresponse"][@"tasks"][@"datafield2"] = @"HelloWorld2";
params[@"zoneresponse"][@"tasks"][@"datafield3"] = @"HelloWorld3";

我认为我的答案会给你的字典操作带来一些清晰的东西。

票数 13
EN

Stack Overflow用户

发布于 2015-04-27 18:46:47

数据发送到服务器数据库的方法的JSON体系结构上下文:

您正在使用一种旧方法(从03‘年开始)发出HTTP POST请求,将可爱的JSON数据放入服务器数据库。它仍然是有效的,没有被弃用,最终是一种可以接受的方法。通常,这种方法的工作原理是使用NSURLConnection设置和触发NSURLRequest,触发请求的ViewController或对象通常实现NSURLConnection协议,因此您有一个回调方法,它接收与NSURLRequests相关的响应。还有一些NSURLCaching和NSHTTPCookStorage可用来避免冗余并加快整个过程。

有一种新的方式(从13‘年开始):

NSURLConnections的后继者是NSURLSession。由于Vladimir Kravchenko的回答侧重于形成要作为参数发送的NSDictionary,他指出您需要使用NSMutableDictionary而不是静态NSDictionary,后者在初始化后无法编辑。不过,为了对您有所帮助,我将重点介绍围绕您的问题的网络方法。

代码语言:javascript
复制
/*
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

你可以在这里找到另一个类似的堆栈溢出问题:Stack Overflow

如果您想要一个使这些问题更简单的网络库,请查看Mattt Thompsons,它可以在以下位置找到:GitHub

有关NSURLConnection与NSURLSession的进一步分析可在此处找到:Ray Wenderlich

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29669296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档