Soy nuevo en el objetivo-c y estoy empezando a esforzarme mucho en la solicitud / respuesta recientemente. Tengo un ejemplo funcional que puede llamar a una URL (a través de http GET) y analizar el json devuelto.
El ejemplo de trabajo de esto está a continuación.
- (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];
}
Mi primera pregunta es: ¿se ampliará este enfoque? ¿O no es asincrónico (lo que significa que bloqueo el hilo de la interfaz de usuario mientras la aplicación está esperando la respuesta)
Mi segunda pregunta es: ¿cómo puedo modificar la parte de solicitud de esto para hacer una POST en lugar de GET? ¿Es simplemente modificar el HttpMethod así?
[request setHTTPMethod:@"POST"];
Y finalmente, ¿cómo agrego un conjunto de datos json a esta publicación como una cadena simple (por ejemplo)
{
"magic":{
"real":true
},
"options":{
"happy":true,
"joy":true,
"joy2":true
},
"key":"123"
}
Gracias de antemano
iphone
objective-c
cocoa-touch
json
nsurlrequest
Toran Billups
fuente
fuente
Respuestas:
Esto es lo que hago (tenga en cuenta que el JSON que va a mi servidor debe ser un diccionario con un valor (otro diccionario) para 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]; }
Los datos recibidos son luego manejados por:
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSDictionary *jsonDict = [jsonString JSONValue]; NSDictionary *question = [jsonDict objectForKey:@"question"];
Esto no está 100% claro y tomará una nueva lectura, pero todo debería estar aquí para comenzar. Y por lo que puedo decir, esto es asincrónico. Mi interfaz de usuario no está bloqueada mientras se realizan estas llamadas. Espero que ayude.
fuente
NSDictionary
método de instanciaJSONRepresentation
. Podría sugerir que use elNSJSONSerialization
método de clasedataWithJSONObject
, en lugar del json-framework .[[NSNumber numberWithUnsignedInt:requestData.length] stringValue]
.Luché con esto por un tiempo. Ejecutando PHP en el servidor. Este código publicará un json y obtendrá la respuesta json del servidor
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 } }];
fuente
Sugeriría usar ASIHTTPRequest
Tenga en cuenta que el autor original interrumpió este proyecto. Consulte la siguiente publicación para conocer las razones y las alternativas: http://allseeing-i.com/%5Brequest_release%5D ;
Personalmente soy un gran fan de AFNetworking
fuente
La mayoría de ustedes ya saben esto por ahora, pero estoy publicando esto, por si acaso, algunos de ustedes todavía están luchando con JSON en iOS6 +.
En iOS6 y posteriores, tenemos la clase NSJSONSerialization que es rápida y no depende de la inclusión de bibliotecas "externas".
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:[resultStr dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
Esta es la forma en que iOS6 y versiones posteriores ahora pueden analizar JSON de manera eficiente. El uso de SBJson también es una implementación previa a ARC y también trae consigo esos problemas si está trabajando en un entorno ARC.
¡Espero que esto ayude!
fuente
Aquí hay un gran artículo usando Restkit
Explica cómo serializar datos anidados en JSON y adjuntar los datos a una solicitud HTTP POST.
fuente
Dado que mi edición de la respuesta de Mike G para modernizar el código fue rechazada 3 a 2 como
Estoy volviendo a publicar mi edición como una respuesta separada aquí. Esta edición elimina la
JSONRepresentation
dependencia conNSJSONSerialization
como sugiere el comentario de Rob con 15 votos a favor.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]; }
Los datos recibidos son luego manejados por:
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSDictionary *question = [jsonDict objectForKey:@"question"];
fuente
Aquí hay un ejemplo actualizado que usa NSURLConnection + sendAsynchronousRequest: (10.7+, iOS 5+), La solicitud "Publicar" sigue siendo la misma que con la respuesta aceptada y se omite aquí para mayor claridad:
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); } } }];
fuente
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];
fuente