AWS SDK - 为 CloudFront 下载实施网络队列

AWS SDK - Implementing a network queue for CloudFront downloads

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

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

我试过使用 NSOperationQueue 并设置 setMaxConcurrentOperationCount,并且所有代码块同时执行。 :(

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

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

TIA

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

I have tried using an NSOperationQueue and setting setMaxConcurrentOperationCount, and all the code blocks execute at once. :(

在没有看到实际代码的情况下很难说出绝对错误的地方,但很可能与以下步骤有关:

  1. 你创造了NSOperationQueue
  2. 例如,您将 maxConcurrentOperationsCount 设置为 2
  3. 你用 AWSContent downloadWithDownloadType:
  4. 添加 4 个方块
  5. 您预计不会再有 2 个下载同时 运行

你可能做错了什么

关键在第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://developer.apple.com/reference/dispatch