我正在尝试将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
我在这里做错了什么?
答案 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];