cómo usar sendAsynchronousRequest: queue: completionHandler:
Pregunta en dos partes
Primera parte: Estoy tratando de crear una solicitud asincrónica a mi base de datos. Actualmente lo estoy haciendo Sincrónicamente, sin embargo, quiero aprender ambas formas para mejorar mi comprensión de lo que está pasando.
Actualmente he configurado mi llamada síncrona de esta manera.
- (IBAction)setRequestString:(NSString *)string
{
//Set database address
NSMutableString *databaseURL = [[NSMutableString alloc] initWithString:@"http://127.0.0.1:8778/instacodeData/"]; // imac development
//PHP file name is being set from the parent view
[databaseURL appendString:string];
//call ASIHTTP delegates (Used to connect to database)
NSURL *url = [NSURL URLWithString:databaseURL];
//SynchronousRequest to grab the data
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSError *error;
NSURLResponse *response;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (!result) {
//Display error message here
NSLog(@"Error");
} else {
//TODO: set up stuff that needs to work on the data here.
NSString* newStr = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
NSLog(@"%@", newStr);
}
}
Creo que lo que tengo que hacer es reemplazar la llamada
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
Con la versión asíncrona
sendAsynchronousRequest:queue:completionHandler:
Sin embargo, no estoy seguro de qué pasar a la cola o completionHandler... Cualquier ejemplo / solución sería muy apreciada.
Segunda parte: He estado leyendo sobre multitarea y me gustaría apoyarlo asegurándome de que mis solicitudes de conexión se completen si hay una interrupción. He estado siguiendo este ejemplo
En él se explica cómo ganar más tiempo si se produce una interrupción, entiendo lo que está haciendo.. ¿pero no cómo aplicarlo a esta conexión? si tienes algún ejemplo / tutorial que me ayude averiguar cómo aplicarlo que sería impresionante!
6 answers
Parte 1:
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if ([data length] > 0 && error == nil)
[delegate receivedData:data];
else if ([data length] == 0 && error == nil)
[delegate emptyReply];
else if (error != nil && error.code == ERROR_CODE_TIMEOUT)
[delegate timedOut];
else if (error != nil)
[delegate downloadError:error];
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-14 01:58:24
Aquí hay una muestra:
NSString *urlAsString = @"http://www.cnn.com";
NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error)
{
if ([data length] >0 && error == nil)
{
// DO YOUR WORK HERE
}
else if ([data length] == 0 && error == nil)
{
NSLog(@"Nothing was downloaded.");
}
else if (error != nil){
NSLog(@"Error = %@", error);
}
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-18 16:42:44
Para el parámetro de cola, prueba esta magia:
[NSOperationQueue mainQueue]
Esto funciona muy bien si está actualizando la interfaz de usuario al completar la solicitud, ya que la cola principal es el hilo principal. Esencialmente le da el comportamiento anterior de NSURLConnection. Sin embargo, si planea escribir en archivo o descomprimir, puede completar en una cola en segundo plano y luego enviar async a la cola principal para las actualizaciones de la interfaz de usuario.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-10 19:10:04
He estado trabajando en un problema similar, publiqué esta pregunta y obtuve una respuesta clara aquí, espero que eso ayude con la Parte 2.
Para la parte 1 lo que los otros mencionados aquí son buenos, pero necesita agregar otra verificación (he modificado una respuesta a continuación). Es posible que su solicitud devolverá digamos un Error 404 (página no encontrada) en cuyo caso no obtendrá y el error y los datos serán > 0. El 200 es una buena respuesta, también puede comprobar el código de estado para 404 o Lo que sea.
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ([data length] >0 && error == nil && [httpResponse statusCode] == 200)
{
// DO YOUR WORK HERE
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:05
Ya que sendAsynchronousRequest:urlRequest queue:queue completionHandler:
ha sido obsoleto en iOS 9, y sugerirá usar NSURLSession
's -dataTaskWithRequest:completionHandler:
en su lugar. Está disponible desde iOS 7 y posteriores .
Original:
NSURL *URL = [NSURL URLWithString:@"http://example.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// ...
}];
Por NSURLSession:
NSURL *URL = [NSURL URLWithString:@"http://example.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
// ...
}];
[task resume];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-20 06:16:01
sendAsynchronousRequest
ha sido obsoleto en Swift. Mover a dataTaskWithRequest
, por suerte se utiliza más o menos de la misma manera.
if let url = NSURL(string:"http://your_url") {
let request:NSURLRequest = NSURLRequest(URL: url)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
});
task.resume()
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-18 05:06:54