【问题标题】:Posting JSON data to server将 JSON 数据发布到服务器
【发布时间】:2015-05-07 10:30:38
【问题描述】:

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

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

NSError *error;

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

我在这里做错了什么?

【问题讨论】:

  • 崩溃发生在哪一行?设置异常断点见stackoverflow.com/a/10830845/123632
  • 应用程序在以下位置崩溃:NSData *requestHandler = [NSURLConnection sendSynchronousRequest:request returnedResponse:&requestResponse error:nil];

标签: objective-c ios8 nsurlconnection


【解决方案1】:

我总是在我的应用程序中使用这种方法来执行 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
}

【讨论】:

  • 谢谢。非常完整且经过深思熟虑。非常感谢。
【解决方案2】:

首先,您创建一个应该包含 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];

就是这样。

【讨论】:

    【解决方案3】:

    试试这个:

         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];
    

    【讨论】:

    • 谢谢 :) 这解决了崩溃,但 responseData 为 nil :(
    • 服务器是否发送响应?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多