4
NSString *saveFilename =
5
[self downloadSavePathFor:url.lastPathComponent];
6
7
NSLog(@"Salvando o arquivo em %@", saveFilename);
8
9
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
10
initWithRequest:request];
11
12
operation.outputStream = [NSOutputStream
13
outputStreamToFileAtPath:saveFilename append:NO];
14
15
[operation setCompletionBlockWithSuccess:
16
^(AFHTTPRequestOperation *op, NSHTTPURLResponse *response) {
17
[_loading stopAnimating];
18
_loading.hidden = YES;
19
[self showMessage:@"Download finalizado com sucesso"];
20
}
21
failure:^(AFHTTPRequestOperation *op, NSError *error) {
22
[self showMessage:
23
[NSString stringWithFormat:@"Erro no download: %@",
24
[error localizedDescription]]];
25
}
26
];
27
28
[operation setDownloadProgressBlock:
29
^(NSUInteger read, long long totalRead,
30
long long totalExpected) {
31
_progressBar.progress = (float)totalRead / (float)totalExpected;
104
Casa do Código
Capítulo
6. Realizando operações com a Internet
32
}];
33
34
_progressBar.hidden = NO;
35
_progressBar.progress = 0;
36
_loading.hidden = NO;
37
[_loading startAnimating];
38
39
[operation start];
40 }
Muitas requisições com o AFNetworking, sejam para enviar ou receber dados,
utilizam um NSURLRequest para fazer as operações. Esse código é construído nas
linhas 2 e 3, enquanto que na linha 9 iniciamos o objeto que irá lidar com as requi-
sições em si, através da classe AFHTTPRequestOperation. O objeto NSURLRequest
encapsula tudo a respeito de uma requisição HTTP, incluindo a URL, os métodos
(GET, POST, PUT, DELETE), os headers e corpo da requisição.
O código que se inicia na linha 15, setCompletionBlockWithSuccess:,
utiliza um recurso avançado de Objective-C chamado blocks, que falando de uma
maneira bem geral são objetos que contêm um comportamento específico, que
será executado em um determinado momento. Blocks são tratados em detalhes no
capítulo sobre Objective-C. O código completo do método inicia na linha 15, com
a operação que deverá ser executada no caso de sucesso da operação, e termina na
linha 26. A linha 21 contêm a declaração do block de código que será executado
no caso da requisição falhar por algum motivo. A assinatura completa do método
é setCompletionBlockWithSuccess:failure:. No caso da operação com-
pletar com sucesso, paramos o indicador de atividade e o escondemos, conforme as
linhas 17 e 18.
Na linha 28 definimos a operação que será executada (que também utiliza blocks)
toda vez que recebermos dados do servidor no caso, pedaços do arquivo que ire-
mos baixar. Na linha 30 atualizamos a barra de progresso com a porcentagem até o
momento, lembrando que os valores da UIProgressBar vão de 0 até 1 (ou seja,
73% é representado como 0.73).
Os códigos definidos em blocos são sempre executados em um outro momento,
ao contrário de métodos normais. Eles são os chamados callback methods. O AF-
Networking trabalha automaticamente em background, o que evita que a UI fique
congelada, o que faria o usuário pensar que o aplicativo travou.
O código do método downloadSavePathFor: está implementado abaixo:
105
6.5. Trabalhando com JSON e imagens remotas
Casa do Código
1 -(NSString *) downloadSavePathFor:(NSString *) filename {
2
NSArray *paths =
3
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
4
NSUserDomainMask, YES);
5
NSString *documentsPath = [paths objectAtIndex:0];
6
return [documentsPath stringByAppendingPathComponent:filename];
7 }
Na linha 1 e 2 pegamos a referência para o caminho do diretório Documents do
aplicativo, e na linha 3 concatenamos com o nome do arquivo que será feito o down-
load. Note que é um código relativamente complicado para uma tarefa tão simples;
como você necessitará do caminho para o diretório Documents diversas vezes em seu
aplicativo caso queira salvar arquivos, é uma boa prática implementá-lo em algum
lugar que possa ser reaproveitado.
Por sua vez, o código do método showMessage: não tem nenhum mistério,
como visto a seguir:
-(void) showMessage:(NSString *) message {
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Aviso"
message:message
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil] autorelease];
[alert show];
}
6.5
Trabalhando com JSON e imagens remotas
Além da classe de uso geral AFHTTPRequestOperation, o AFNetworking vem
com algumas outras classes bastante práticas para lidar com JSON, XML e carrega-
mento assíncrono de imagens esta última se destaca por ser uma grande mão na
roda, pois nos livra de ter que programar muita coisa caso fossemos ter que fazer o
processo manualmente.
106
Casa do Código
Capítulo 6. Realizando operações com a Internet
JSON
JSON é um formato simples para transferir dados. É um subconjunto
da notação de objeto de JavaScript, mas seu uso não requer JavaScript ex-
clusivamente. É uma alternativa ao XML e também possibilita organizar
os dados de forma