80 votes

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

Je suis nouveau sur objective-c et je commence à mettre beaucoup d'effort dans la demande/réponse de ces dernières. J'ai un exemple de travail que l'on peut appeler une url (via http GET) et parser le json retourné.

L'exemple de ce qui 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([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];
}

Ma première question est - ce l'approche de l'échelle? Ou n'est-ce pas async (sens-je bloquer le thread de l'INTERFACE utilisateur, tandis que l'application est en attente de la réponse)

Ma deuxième question est - comment pourrais-je modifier la demande de la partie de ce faire un POST au lieu de GET? Est-il tout simplement de modifier la HttpMethod comme?

[request setHTTPMethod:@"POST"];

Et enfin - comment puis-je ajouter un jeu de données json à ce post comme une simple chaîne de caractères (par exemple)

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

Je vous remercie à l'avance

105voto

Mike G Points 576

Voici ce que je fais (veuillez noter que le JSON va mon serveur doit être un dictionnaire, avec une valeur (un autre dictionnaire) pour key = question..c'est à dire {:question => { dictionnaire } } ):

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

Le receivedData est ensuite géré par:

NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [jsonString JSONValue];
NSDictionary *question = [jsonDict objectForKey:@"question"];

Ce n'est pas 100% clair et prendra un certain re-lecture, mais tout devrait être ici pour obtenir vous avez commencé. Et de ce que je peux dire, ce est asynchrone. Mon INTERFACE n'est pas enfermé alors que ces appels sont effectués. Espérons que cela aide.

6voto

vikingosegundo Points 30323

Je suggère d'utiliser ASIHTTPRequest

ASIHTTPRequest est un outil facile à utiliser wrapper autour de la CFNetwork API fait quelques-uns des aspects les plus ennuyeux de communiquer avec des serveurs web plus facile. Il est écrit en Objective-C et travaille à la fois sur Mac OS X et iPhone des applications.

Il convient d'effectuer le HTTP de base les demandes et d'interagir avec RESTE à base de services (GET / POST / PUT / SUPPRIMER). Inclus ASIFormDataRequest sous-classe en fait facile à soumettre publier des données et des fichiers à l'aide de " multipart/form-data.


Veuillez noter que l'auteur original abandonnées avec ce projet. Voir la followring poste pour des raisons et des solutions de rechange: http://allseeing-i.com/%5Brequest_release%5D;

Personnellement, je suis un grand fan de AFNetworking

3voto

tony.stack Points 543

La plupart d'entre vous savent déjà cela, mais je suis ce détachement, juste au cas où, certains d'entre vous sont encore aux prises avec JSON dans iOS6+.

Dans iOS6 et plus tard, nous avons le NSJSONSerialization Classe qui est rapide et n'a pas de dépendance, y compris "à l'extérieur" des bibliothèques.

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

C'est la façon dont iOS6 et, plus tard, peut maintenant analyser JSON efficacement.L'utilisation de SBJson est également pré-ARC de mise en œuvre et apporte avec elle de ces questions trop si vous travaillez dans un ARC de l'environnement.

J'espère que cela aide!

2voto

cevaris Points 1145

Voici un excellent article à l'aide de Restkit

Il explique sur la sérialisation de données imbriquées en JSON et de fixer les données d'une requête HTTP POST.

0voto

auco Points 2663

Voici une mise à jour de l'exemple qui est à l'aide de NSURLConnection +sendAsynchronousRequest: (10.7+, iOS 5+), La demande de "Post" reste le même qu'avec la accepté de répondre, et est omis ici par souci de clarté:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X