如何使用NSURLRequest发送Http请求中的json数据
我是新来的Objective-C,而且我已经开始为最近的请求/响应付出很大的努力。 我有一个工作的例子,可以调用一个url(通过http GET)并parsing返回的json。
下面的工作示例如下
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [responseData setLength:0]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [responseData appendData:data]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [connection release]; //do something with the json that comes back ... (the fun part) } - (void)viewDidLoad { [self searchForStuff:@"iPhone"]; } -(void)searchForStuff:(NSString *)text { responseData = [[NSMutableData data] retain]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.whatever.com/json"]]; [[NSURLConnection alloc] initWithRequest:request delegate:self]; }
我的第一个问题是 – 这种方法是否会扩大? 或者这不是asynchronous(这意味着当应用程序正在等待响应时阻止UI线程)
我的第二个问题是 – 我怎么可以修改这个请求部分做POST而不是GET? 仅仅是这样修改HttpMethod?
[request setHTTPMethod:@"POST"];
最后 – 如何添加一组json数据作为一个简单的string(例如)
{ "magic":{ "real":true }, "options":{ "happy":true, "joy":true, "joy2":true }, "key":"123" }
先谢谢你
这是我做的(请注意,去我的服务器的JSON需要是一个字典与一个值(另一个字典)的key = question..ie {:question => {dictionary}}):
NSArray *objects = [NSArray arrayWithObjects:[[NSUserDefaults standardUserDefaults]valueForKey:@"StoreNickName"], [[UIDevice currentDevice] uniqueIdentifier], [dict objectForKey:@"user_question"], nil]; NSArray *keys = [NSArray arrayWithObjects:@"nick_name", @"UDID", @"user_question", nil]; NSDictionary *questionDict = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; NSDictionary *jsonDict = [NSDictionary dictionaryWithObject:questionDict forKey:@"question"]; NSString *jsonRequest = [jsonDict JSONRepresentation]; NSLog(@"jsonRequest is %@", jsonRequest); NSURL *url = [NSURL URLWithString:@"https://xxxxxxx.com/questions"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody: requestData]; NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; if (connection) { receivedData = [[NSMutableData data] retain]; }
receivedData然后被处理:
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSDictionary *jsonDict = [jsonString JSONValue]; NSDictionary *question = [jsonDict objectForKey:@"question"];
这不是100%清楚,将需要一些重新阅读,但一切都应该在这里让你开始。 从我所知道的来看,这是asynchronous的。 这些调用进行时,我的用户界面没有被locking。 希望有所帮助。
我会build议使用ASIHTTPRequest
ASIHTTPRequest是一个易于使用的CFNetwork API封装,使得与Web服务器通信更加单调乏味。 它是用Objective-C编写的,适用于Mac OS X和iPhone应用程序。
它适合执行基本的HTTP请求并与基于REST的服务(GET / POST / PUT / DELETE)交互。 包含的ASIFormDataRequest子类可以使用multipart / form-data轻松提交POST数据和文件。
请注意,原作者已经停止了这个项目。 查看下面的post,了解原因和备选scheme: http ://allseeing-i.com/%5Brequest_release%5D;
就我个人而言,我是AFNetworking的忠实粉丝
我挣扎了一会儿。 在服务器上运行PHP。 这段代码将会发布一个json并从服务器获取json的回复
NSURL *url = [NSURL URLWithString:@"http://example.co/index.php"]; NSMutableURLRequest *rq = [NSMutableURLRequest requestWithURL:url]; [rq setHTTPMethod:@"POST"]; NSString *post = [NSString stringWithFormat:@"command1=c1&command2=c2"]; NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding]; [rq setHTTPBody:postData]; [rq setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [NSURLConnection sendAsynchronousRequest:rq queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { if ([data length] > 0 && error == nil){ NSError *parseError = nil; NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; NSLog(@"Server Response (we want to see a 200 return code) %@",response); NSLog(@"dictionary %@",dictionary); } else if ([data length] == 0 && error == nil){ NSLog(@"no data returned"); //no data, but tried } else if (error != nil) { NSLog(@"there was a download error"); //couldn't download } }];
你们中的大多数人已经知道这一点,但我发布这个,只是incase,你们中的一些人仍然努力在iOS6 +的JSON。
在iOS6和更高版本中,我们拥有快速的NSJSONSerialization类 ,并且不依赖于包含“外部”库。
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:[resultStr dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
这是iOS6及更高版本现在可以高效地parsingJSON的方式.SBJson的使用也是ARC之前的实现,如果您在ARC环境中工作,也会带来这些问题。
我希望这有帮助!
这是一个使用Restkit的好文章
它解释了将嵌套数据序列化为JSON并将数据附加到HTTP POST请求。
由于我编辑迈克G的代码现代化的答案被拒绝3至2为
这个编辑是为了解决这个post的作者,并且作为一个编辑没有任何意义。 它应该被写为评论或答案
我在这里重新发布我的编辑作为一个单独的答案。 这个编辑消除了与NSJSONSerialization
的JSONRepresentation
依赖关系,Rob的评论有15个upvotesbuild议。
NSArray *objects = [NSArray arrayWithObjects:[[NSUserDefaults standardUserDefaults]valueForKey:@"StoreNickName"], [[UIDevice currentDevice] uniqueIdentifier], [dict objectForKey:@"user_question"], nil]; NSArray *keys = [NSArray arrayWithObjects:@"nick_name", @"UDID", @"user_question", nil]; NSDictionary *questionDict = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; NSDictionary *jsonDict = [NSDictionary dictionaryWithObject:questionDict forKey:@"question"]; NSLog(@"jsonRequest is %@", jsonRequest); NSURL *url = [NSURL URLWithString:@"https://xxxxxxx.com/questions"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSData *requestData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil]; //TODO handle error [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody: requestData]; NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; if (connection) { receivedData = [[NSMutableData data] retain]; }
receivedData然后被处理:
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSDictionary *question = [jsonDict objectForKey:@"question"];
下面是一个使用NSURLConnection + sendAsynchronousRequest的更新示例:(10.7+,iOS 5+),“Post”请求与接受的答案保持一致,为了清楚起见,在这里省略:
NSURL *apiURL = [NSURL URLWithString: [NSString stringWithFormat:@"http://www.myserver.com/api/api.php?request=%@", @"someRequest"]]; NSURLRequest *request = [NSURLRequest requestWithURL:apiURL]; // this is using GET, for POST examples see the other answers here on this page [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if(data.length) { NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; if(responseString && responseString.length) { NSLog(@"%@", responseString); } } }];
你可以尝试这个代码发送jsonstring
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:ARRAY_CONTAIN_JSON_STRING options:NSJSONWritin*emphasized text*gPrettyPrinted error:NULL]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSString *WS_test = [NSString stringWithFormat:@"www.test.com?xyz.php¶m=%@",jsonString];