将JSON数据发布到服务器

时间:2015-05-07 10:30:38

标签: objective-c ios8 nsurlconnection

我正在尝试将JSON数据发布到服务器。 我的JSON是: { “用户名”:”样品” “密码”:“密码-1” }

我将它发送到服务器的方式是:

NSError *错误;

NSString *data = [NSString stringWithFormat:@"{\"username\":\"%@\",\"password\":\"%@\"}",_textFieldUserName.text,_textFieldPasssword.text];
NSData *postData = [data dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSData *jsonData = [NSJSONSerialization JSONObjectWithData:postData options:0 error:&error];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"My URL"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:jsonData];

NSURLResponse *requestResponse;
NSData *requestHandler = [NSURLConnection sendSynchronousRequest:request returningResponse:&requestResponse error:nil];

NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:requestHandler options:0 error:&error];
NSLog(@"resposne dicionary is %@",responseDictionary);

NSString *requestReply = [[NSString alloc] initWithBytes:[requestHandler bytes] length:[requestHandler length] encoding:NSASCIIStringEncoding];
NSLog(@"requestReply: %@", requestReply);

创建的JsonData是服务器接受的有效JSON。 但该应用程序崩溃,错误是:

- [__ NSCFDictionary长度]:无法识别的选择器发送到实例0x1702654c0

我在这里做错了什么?

3 个答案:

答案 0 :(得分:3)

我总是在我的应用中使用此方法来执行API调用。这是post方法。它是异步的,因此您可以指定在服务器应答时调用的回调。

-(void)placePostRequestWithURL:(NSString *)action withData:(NSDictionary *)dataToSend withHandler:(void (^)(NSURLResponse *response, NSData *data, NSError *error))ourBlock {
    NSString *urlString = [NSString stringWithFormat:@"%@", action];
    NSLog(@"%@", urlString);

    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    NSError *error;

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dataToSend options:0 error:&error];

    NSString *jsonString;
    if (! jsonData) {
        NSLog(@"Got an error: %@", error);
    } else {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

        NSData *requestData = [NSData dataWithBytes:[jsonString UTF8String] length:[jsonString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

        [request setHTTPMethod:@"POST"];
        [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
        [request setValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
        [request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[requestData length]] forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody: requestData];

        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:ourBlock];
    }
}

您可以轻松地将其称为:

- (void) login:(NSDictionary *)data
                    calledBy:(id)calledBy
                 withSuccess:(SEL)successCallback
                  andFailure:(SEL)failureCallback{
    [self placePostRequestWithURL:@"yourActionUrl"
                  withData:data
               withHandler:^(NSURLResponse *response, NSData *rawData, NSError *error) {
                   NSString *string = [[NSString alloc] initWithData:rawData
                                                            encoding:NSUTF8StringEncoding];

                   NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
                   NSInteger code = [httpResponse statusCode];
                   NSLog(@"%ld", (long)code);

                   if (!(code >= 200 && code < 300)) {
                       NSLog(@"ERROR (%ld): %@", (long)code, string);
                       [calledBy performSelector:failureCallback withObject:string];
                   } else {
                       NSLog(@"OK");

                       NSDictionary *result = [NSDictionary dictionaryWithObjectsAndKeys:
                                               string, @"id",
                                               nil];
                       [calledBy performSelector:successCallback withObject:result];
                   }
               }];
}

最后,你调用:

NSDictionary *dataToSend = [NSDictionary dictionaryWithObjectsAndKeys:
_textFieldUserName.text, @"username", 
_textFieldPasssword.text, @"password", nil];

[self login:dataToSend 
    calledBy:self 
    withSuccess:@selector(loginDidEnd:) 
    andFailure:@selector(loginFailure:)];

不要忘记定义你的回调:

- (void)loginDidEnd:(id)result{
    NSLog(@"loginDidEnd:");
    // Do your actions
}

- (void)loginFailure:(id)result{
    NSLog(@"loginFailure:");
    // Do your actions
}

答案 1 :(得分:1)

首先创建一个应该包含JSON数据的NSString *。如果用户名和密码包含任何异常字符,这通常不起作用。例如,我确保我的密码中有一个引号,以确保愚蠢的软件崩溃。

使用ASCII编码将该字符串转换为NSData *。因此,如果我的用户名包含任何不在ASCII字符集中的字符,那么你得到的就是废话。

然后使用解析器将其转换为字典或数组,但将结果存储到NSData中。有可能解析失败并且你得到nil,否则你得到NSDictionary *或NSArray *,但绝大多数都不是NSData *。

以下是如何正确执行此操作:创建字典,然后将其转换为NSData。

NSDictionary* dict = @{ @"username": _textFieldUserName.text, 
                        @"password": _textFieldPasssword.text };
NSError* error; 
NSData* data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];

那就是它。

答案 2 :(得分:0)

试试这个:

     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:@"My URL"];
        if (!request) NSLog(@"Error creating the URL Request");

        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:@"text/json" forHTTPHeaderField:@"Content-Type"];
        NSLog(@"will create connection");

        // Send a synchronous request
        NSURLResponse * response = nil;
        NSError * NSURLRequestError = nil;
        NSData * responseData = [NSURLConnection sendSynchronousRequest:request
                                              returningResponse:&response
                                               error:&NSURLRequestError];