Pergunta

Acabei de começar a usar o AFNetworking e até agora funcionou bem apenas para obter dados da web.

Mas agora tenho uma lista de arquivos que precisam ser baixados para o dispositivo

for(NSDictionary *issueDic in data)
{
    Issue *issue = [[Issue alloc] init];
    ...
    [self getOrDownloadCover:issue];
    ...
}

getOrDownloadCover:issue verifica se um arquivo já existe localmente, se existir, apenas salva esse caminho, caso contrário, baixa o arquivo de uma determinada URL

- (void)getOrDownloadCover:(Issue *)issue
{
    NSLog(@"issue.thumb: %@", issue.thumb);

    NSString *coverName = [issue.thumb lastPathComponent];

    NSLog(@"coverName: %@", coverName);

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    __block NSString *filePath = [documentsDirectory stringByAppendingPathComponent:coverName];

    if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
    {
        // Cover already exists
        issue.thumb_location = filePath;

        NSLog(@"issue.thumb_location: %@", filePath);
    }
    else 
    {
        NSLog(@"load thumb");

        // Download the cover
        NSURL *url = [NSURL URLWithString:issue.thumb];
        AFHTTPClient *httpClient = [[[AFHTTPClient alloc] initWithBaseURL:url] autorelease];
        NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:issue.thumb parameters:nil];

        AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
        operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];

        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        issue.thumb_location = filePath;

        NSLog(@"issue.thumb_location: %@", filePath);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"FAILED");
    }];
        [operation start];
    }
}

getOrDownloadCover:issue pode ser chamado 20 vezes seguidas, então eu precisaria colocar todas as minhas solicitações em uma fila e, quando a fila for concluída, ele ainda poderá salvar o caminho (ou apenas enviar uma notificação, já que Eu já sei qual é o caminho)

Alguma sugestão para isso?

Foi útil?

Solução

Adicione um NSOperationQueue para um objeto do qual você pode obter a instância em qualquer ponto do seu aplicativo, por exemplo, em seu appDelegate.Depois é só adicionar AFHTTPRequestOperation para esta fila como:

[[(AppDelegate *) [UIApplication sharedApplication].delegate operartionQueue] addOperation:operation];

Basta lidar com o salvamento no bloco de conclusão, chamar um método deste bloco no thread principal ou postar um NSNotification.

Para chamar o thread principal use GCD :

dispatch_async(dispatch_get_main_queue(), ^{
    // Call any method from on the instance that created the operation here.
    [self updateGUI]; // example
});

Outras dicas

Não tenho certeza se isso é útil, mas ...

Em vez de usar seu próprio OperationQueue, você pode usar o OperationQueue do AFHTTPClient.Enfileirar operações únicas com enqueueHTTPOperation ou enfileirar uma matriz de operações com enqueueBatchOperations (estou lembrando esses nomes de métodos da memória, provavelmente um pouco).

No que diz respeito ao armazenamento de dados específicos para cada operação, você pode subclassificar AFHTTPRequestOperation e definir propriedades para o caminho que deseja armazenar.Algo assim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top