miquelcamps/Freelance-Betabeers-iOS-app — pull request #11 by JaviSoto (2012-06-24 07:30:14+00:00)
Title: Making requests asynchronous to not block the User Interface while downloading

**Jamás** hagas algo como

```objc
NSData *jobData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
```

en un método de un controlador por ejemplo. Ese método va a tardar en devolver el control tanto como tarde el request. En un teléfono móvil, esto puede ser perfectamente un minuto si tienes poca cobertura. Durante todo ese tiempo, la interfaz permanece bloqueada, porque el hilo principal está ejecutando esa función, y hasta que no termine, no puede hacer nada más.
En el hilo principal es donde se gestionan los eventos (por ejemplo, cualquier cosa que hagas tocando la pantalla). Si no puede hacer nada, la UI se para, y da la sensación de que la aplicación está bloqueada.

Para arreglar esto me ayudo de GCD usando ```dispatch_async()```:

```objc
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Lo que haha aquí corre en otro hilo. Puede tardar lo que sea que no va a bloquear la UI
dispatch_async(dispatch_get_main_queue(), ^{
// Esto vuelve a correr en el hilo principal. Aquí llamo al callback que actualizará la UI, ya que no puedes hacer nada con la UI en otro hilo que no sea el principal!!!
});
});
```

Ejemplo: el método de ```TipsDataProvider```:

```objc
- (void)requestTipWithCompletionBlock:(TipsDataProviderCompletionBlock)completionBlock
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *url = @"http://migueldev.com/freelance/consejos.php";

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];

NSString *tip = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(tip);
});
});
}
```