0

AFNetworking在我的项目中使用。我需要弄清楚的主要事情是如何检测我的所有文件从远程服务器加载到 iOS 设备上的 Document 目录的时刻。

现在我有这个架构:

此方法有循环,它调用下载新的 Zip 文件方法。请查看-stopLoad循环结束后它将立即调用的方法。由于以下原因:

- (void)startLoad {
    for (NSDictionary *item in items) {

       if ([self checkIfNeedUpdateQZTestModelWithItem:item]) {
          NSString *urlString = [item objectForKey:@"url"];

          NSNumber *updateID = [item objectForKey:@"update_id"];

          [self downloadZipFileWithUrlString:urlString andUpdateID:updateID];
        }
    }
    [self stopLoad];
}

- (void)downloadZipFileWithUrlString:(NSString *)urlString andUpdateID:(NSNumber *)updateId
{
    NetworkManagerBlock block = ^ {
        NSString *fileName = [self fileNameFromUrlString:urlString];
        FileManager *fileManager = [FileManager new];
        [fileManager unZipFileWithFileName:fileName andUpdateID:updateId];
    };

    [self downloadFileWithUrlString:urlString withCompletionBlock:block];
}

- (void)downloadFileWithUrlString:(NSString *)urlString withCompletionBlock:(NetworkManagerBlock)block
{
    NSURL *url = [NSURL URLWithString:urlString];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *fileName = [self fileNameFromUrlString:urlString];
    NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:fileName];

    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        block();

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"Error: %@", error);

    }];

    [operation start];
}

我假设立即调用的原因-stopLoad是异步操作。因此,如果我需要下载 10 或 20 个文件,我不知道何时会下载最后一个文件。所以在我的情况下,-stopLoad方法并没有告诉我完成它在结束循环后调用的所有操作。

我想我需要一些操作堆栈或类似的东西来确定所有文件何时加载。我对吗?但我仍在考虑正确的解决方案。有任何想法吗?谢谢。

我还添加了NSInteger变量operationsCount。我operationsCount在每个setCompletionBlockWithSuccess块中减少,然后检查变量值是否等于 -1,然后我调用-stopLoad它并且它可以工作,但我认为这不是一个漂亮的解决方案。

4

2 回答 2

2

你为什么不让你的服务器提供一些关于有多少下载的信息?它可能是一个简单的 API 调用,例如

http://yoursever.com/fileList?user=johnDoe&filter=important

给你类似的东西

{
 "status": "OK",
 "fileList": ["file1", "file2", "file3"]
}

现在您可以遍历文件并在stopLoad完成后调用您的例程。

于 2013-07-25T14:42:15.647 回答
1

stopLoad is called synchronously, while all of the requests are trying to load asynchronously. If that method does what it sounds like it does, your requests will all be cancelled shortly after being started.

To get a handler for when a batch of request operations completes, use HTTPClient -enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock:.

于 2013-07-25T14:43:19.710 回答