Comment envoyer des données json dans la requête HTTP à l’aide de NSURLRequest

Je suis nouveau à objective-c et je commence à mettre beaucoup d’efforts dans la demande / réponse à la date récente. J’ai un exemple de travail qui peut appeler une URL (via http GET) et parsingr le retour de json.

L’exemple de travail de ceci est ci-dessous

- (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([NSSsortingng ssortingngWithFormat:@"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:(NSSsortingng *)text { responseData = [[NSMutableData data] retain]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithSsortingng:@"http://www.whatever.com/json"]]; [[NSURLConnection alloc] initWithRequest:request delegate:self]; } 

Ma première question est la suivante: cette approche va-t-elle évoluer? Ou est-ce que ce n’est pas asynchrone (ce qui signifie que je bloque le thread d’interface utilisateur pendant que l’application attend la réponse)

Ma deuxième question est la suivante: comment puis-je modifier la partie requête de ce document pour effectuer un POST au lieu de GET? Est-ce simplement pour modifier la méthode HttpMet comme ça?

 [request setHTTPMethod:@"POST"]; 

Et enfin – comment append un dataset json à cette publication sous forme de chaîne simple (par exemple)

 { "magic":{ "real":true }, "options":{ "happy":true, "joy":true, "joy2":true }, "key":"123" } 

Merci d’avance

Voici ce que je fais (s’il vous plaît noter que le JSON allant à mon serveur doit être un dictionnaire avec une valeur (un autre dictionnaire) pour 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"]; NSSsortingng *jsonRequest = [jsonDict JSONRepresentation]; NSLog(@"jsonRequest is %@", jsonRequest); NSURL *url = [NSURL URLWithSsortingng:@"https://xxxxxxx.com/questions"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8SsortingngEncoding]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:[NSSsortingng ssortingngWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody: requestData]; NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; if (connection) { receivedData = [[NSMutableData data] retain]; } 

Le receiveData est ensuite traité par:

 NSSsortingng *jsonSsortingng = [[NSSsortingng alloc] initWithData:data encoding:NSUTF8SsortingngEncoding]; NSDictionary *jsonDict = [jsonSsortingng JSONValue]; NSDictionary *question = [jsonDict objectForKey:@"question"]; 

Ce n’est pas clair à 100% et cela nécessitera une relecture, mais tout devrait être là pour vous aider à démarrer. Et d’après ce que je peux dire, c’est asynchrone. Mon interface utilisateur n’est pas verrouillée pendant ces appels. J’espère que cela pourra aider.

Je suggère d’utiliser ASIHTTPRequest

ASIHTTPRequest est un wrapper facile à utiliser autour de l’API CFNetwork qui facilite certains des aspects les plus fastidieux de la communication avec les serveurs Web. Il est écrit en Objective-C et fonctionne dans les applications Mac OS X et iPhone.

Il convient pour exécuter des requêtes HTTP de base et interagir avec des services basés sur REST (GET / POST / PUT / DELETE). La sous-classe ASIFormDataRequest incluse facilite la soumission de données et de fichiers POST à ​​l’aide de multipart / form-data.


Veuillez noter que l’auteur original a abandonné ce projet. Voir l’article suivant pour des raisons et des alternatives: http://allseeing-i.com/%5Brequest_release%5D ;

Personnellement, je suis un grand fan de AFNetworking

J’ai lutté avec ça pendant un moment. Exécuter PHP sur le serveur. Ce code affichera un fichier json et obtiendra la réponse json du serveur

 NSURL *url = [NSURL URLWithSsortingng:@"http://example.co/index.php"]; NSMutableURLRequest *rq = [NSMutableURLRequest requestWithURL:url]; [rq setHTTPMethod:@"POST"]; NSSsortingng *post = [NSSsortingng ssortingngWithFormat:@"command1=c1&command2=c2"]; NSData *postData = [post dataUsingEncoding:NSASCIISsortingngEncoding]; [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 sortinged } else if (error != nil) { NSLog(@"there was a download error"); //couldn't download } }]; 

La plupart d’entre vous le savent déjà, mais je poste ceci, juste au cas où, certains d’entre vous ont encore du mal avec JSON dans iOS6 +.

Dans iOS6 et les versions ultérieures, nous avons la classe NSJSONSerialization qui est rapide et ne dépend pas de l’inclusion de bibliothèques «externes».

 NSDictionary *result = [NSJSONSerialization JSONObjectWithData:[resultStr dataUsingEncoding:NSUTF8SsortingngEncoding] options:0 error:nil]; 

Voici comment iOS6 et les versions ultérieures peuvent désormais parsingr efficacement JSON. L’utilisation de SBJson est également une implémentation pré-ARC et apporte également ces problèmes si vous travaillez dans un environnement ARC.

J’espère que ça aide!

Voici un excellent article utilisant Restkit

Il explique la sérialisation des données nestedes dans JSON et la liaison des données à une requête HTTP POST.

Depuis mon édition à la réponse de Mike G pour moderniser le code a été rejetée 3 à 2 comme

Cette édition était destinée à s’adresser à l’auteur du message et n’a aucun sens en tant qu’édition. Il aurait dû être écrit comme un commentaire ou une réponse

Je republie mon édition en tant que réponse séparée ici. Cette modification supprime la dépendance JSONRepresentation avec NSJSONSerialization comme le NSJSONSerialization le commentaire de Rob avec 15 notes avancées.

  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 URLWithSsortingng:@"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:[NSSsortingng ssortingngWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody: requestData]; NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; if (connection) { receivedData = [[NSMutableData data] retain]; } 

Le receiveData est ensuite traité par:

 NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSDictionary *question = [jsonDict objectForKey:@"question"]; 

Voici un exemple mis à jour qui utilise NSURLConnection + sendAsynchronousRequest: (10.7+, iOS 5+), la demande “Post” rest la même que pour la réponse acceptée et est omise ici pour des raisons de clarté:

 NSURL *apiURL = [NSURL URLWithSsortingng: [NSSsortingng ssortingngWithFormat:@"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) { NSSsortingng *responseSsortingng = [[NSSsortingng alloc] initWithData:data encoding:NSUTF8SsortingngEncoding]; if(responseSsortingng && responseSsortingng.length) { NSLog(@"%@", responseSsortingng); } } }]; 

Vous pouvez essayer ce code pour envoyer la chaîne json

 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:ARRAY_CONTAIN_JSON_STRING options:NSJSONWritin*emphasized text*gPrettyPrinted error:NULL]; NSSsortingng *jsonSsortingng = [[NSSsortingng alloc] initWithData:jsonData encoding:NSUTF8SsortingngEncoding]; NSSsortingng *WS_test = [NSSsortingng ssortingngWithFormat:@"www.test.com?xyz.php&param=%@",jsonSsortingng];