AWS开发工具包 - 为CloudFront下载实现网络队列

时间:2016-10-15 01:30:23

标签: ios amazon-web-services amazon-cloudfront aws-sdk nsoperationqueue

我目前正在开发一个iOS项目,该项目利用AWS SDK将大型媒体文件下载到设备。我正在使用CloudFront分发内容,并且下载工作正常,但是我在为这些操作实现网络队列时遇到问题。无论我尝试什么,所有文件都想立即下载。

我正在使用AWSContent downloadWithDownloadType:方法启动和监控实际下载的进度。

我尝试使用NSOperationQueue并设置setMaxConcurrentOperationCount,并且所有代码块都会立即执行。 :(

我觉得可能可以使用AWSServiceConfiguration中的AppDelegate进行配置,但文档对于您可以传递到该对象的变量非常模糊...... http://docs.aws.amazon.com/AWSiOSSDK/latest/Classes/AWSServiceConfiguration.html

有没有人有这方面的经验?

TIA

1 个答案:

答案 0 :(得分:2)

您的问题很可能是您误解了异步操作的方法。

  

我尝试过使用NSOperationQueue和设置   setMaxConcurrentOperationCount,所有代码块都在执行   一旦。 :(

如果没有看到实际代码,很难说出什么是绝对错误的,但很可能它与以下步骤有关:

  1. 您创建了NSOperationQueue
  2. 您将maxConcurrentOperationsCount设置为2,例如
  3. 使用AWSContent downloadWithDownloadType:
  4. 添加4个块
  5. 您预计不会再同时运行2次下载
  6. 你可能做错了什么

    关键是在第3点内部。该块究竟是做什么的?我的猜测是它在实际下载完成之前完成。所以如果你有类似的东西:

    NSOperationQueue *queue = [NSOperationQueue new];
    queue.maxConcurrentOperationsCount = 2;
    for (AWSContent *content in contentArray) { // Assume you already do have this array
        [queue addOperationWithBlock:^() {
            [content downloadWithDownloadType:AWSContentDownloadTypeIfNotCached
                             pinOnCompletion:YES
                               progressBlock:nil
                           completionHandler:^(AWSContent *content, NSData *data, NSError *error) {
                // do some stuff here on completion
            }];
        }];
    }
    

    您的块在下载完成之前退出,允许下一个块在队列中运行并开始进一步下载。

    尝试什么

    您应该简单地向块添加一些同步机制,以便仅在完成块上完成操作。说:

    NSOperationQueue *queue = [NSOperationQueue new];
    queue.maxConcurrentOperationsCount = 2;
    for (AWSContent *content in contentArray) { // Assume you already do have this array
        [queue addOperationWithBlock:^() {
            dispatch_semaphore_t dsema = dispatch_semaphore_create(0);
            [content downloadWithDownloadType:AWSContentDownloadTypeIfNotCached
                             pinOnCompletion:YES
                               progressBlock:nil
                           completionHandler:^(AWSContent *content, NSData *data, NSError *error) {
                // do some stuff here on completion
                // ...
                dispatch_semaphore_signal(dsema); // it's important to call this function in both error and success cases of download to free the block from queue
            }];
            dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER); // or another dispatch_time if you want your custom timeout instead of AWS
        }];
    }
    

    有效的答案是https://stackoverflow.com/a/4326754/2392973

    您只需在操作队列中安排大量此类阻止。

    更多阅读

    https://developer.apple.com/reference/dispatch