iphone - NSURLRequest: Publicar datos y leer la página publicada
objective-c ios (3)
Algunas cosas primero
- Decida cómo desea codificar sus datos: la codificación JSON o url es un buen comienzo.
- Decidir sobre un valor de retorno: será 1, VERDADERO o 0, FALSO o incluso SÍ / nada nulo / nada.
- Lee sobre el sistema de carga de URL , es tu amigo.
Trate de hacer que todas sus conexiones url sean asíncronas para que su interfaz de usuario se mantenga receptiva Puede hacer esto con devoluciones de llamada NSURLConnectionDelegate. NSURLConnection tiene un pequeño inconveniente: su código debe estar desacoplado. Cualquier variable que desee disponible en las funciones de delegado deberá guardarse en ivars o en el dictado de información de usuario de su solicitud.
Alternativamente, puede usar GCD, que, cuando se combina con los calificadores __block, le permite especificar el código de error / retorno en el punto que lo declara, lo que es útil para las búsquedas fuera de línea.
Sin más preámbulos, aquí hay un codificador url rápido y sucio:
- (NSData*)encodeDictionary:(NSDictionary*)dictionary {
NSMutableArray *parts = [[NSMutableArray alloc] init];
for (NSString *key in dictionary) {
NSString *encodedValue = [[dictionary objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue];
[parts addObject:part];
}
NSString *encodedDictionary = [parts componentsJoinedByString:@"&"];
return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];
}
Usar una biblioteca JSON como JSONKit facilita la codificación de las cosas, ¡considérelo!
Método 1: devoluciones de llamada asíncronas NSURLConnectionDelegate:
// .h
@interface ViewController : UIViewController<NSURLConnectionDelegate>
@end
// .m
@interface ViewController () {
NSMutableData *receivedData_;
}
@end
...
- (IBAction)asyncButtonPushed:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://localhost/"];
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:@"user", @"username",
@"password", @"password", nil];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[receivedData_ setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData_ appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"Succeeded! Received %d bytes of data", [receivedData_ length]);
NSString *responeString = [[NSString alloc] initWithData:receivedData_
encoding:NSUTF8StringEncoding];
// Assume lowercase
if ([responeString isEqualToString:@"true"]) {
// Deal with true
return;
}
// Deal with an error
}
Método 2 - Función asíncrona de Grand Central Dispatch:
// .m
- (IBAction)dispatchButtonPushed:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://www.apple.com/"];
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:@"user", @"username",
@"password", @"password", nil];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Peform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
// Deal with your error
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSLog(@"HTTP Error: %d %@", httpResponse.statusCode, error);
return;
}
NSLog(@"Error %@", error);
return;
}
NSString *responeString = [[NSString alloc] initWithData:receivedData
encoding:NSUTF8StringEncoding];
// Assume lowercase
if ([responeString isEqualToString:@"true"]) {
// Deal with true
return;
}
// Deal with an error
// When dealing with UI updates, they must be run on the main queue, ie:
// dispatch_async(dispatch_get_main_queue(), ^(void){
//
// });
});
}
Método 3: utilizar una función de conveniencia NSURLConnection
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler
Espero que esto ayude.
En iOS (destino actual 5.0, Base SDK 5.1), ¿cómo puedo enviar una solicitud de publicación a un servidor y luego leer el contenido de la página? Por ejemplo, la página toma un nombre de usuario y contraseña, y luego deja de ser verdadero o falso. Esto es solo para una mejor comprensión de NSURLRequest.
¡Gracias por adelantado!
Este proyecto puede ser muy útil para su propósito. Se ocupará de sus descargas y las almacenará localmente. Consulte el enlace https://github.com/amitgowda/AGInternetHandler
NSData *postData = [someStringToPost dataUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:someURLString];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:@"POST"];
[req setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[req setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[req setHTTPBody:postData];
NSError *err = nil;
NSHTTPURLResponse *res = nil;
NSData *retData = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&err];
if (err)
{
//handle error
}
else
{
//handle response and returning data
}