我最近在我的应用程序中实现了新的AWS 2.0 iOS SDK(yay,cocoapods!),并使用亚马逊管理的示例代码来正确配置访问和下载。我可以毫无问题地成功下载单个项目,但我需要能够下载基于当前tableview动态生成的多个文件。似乎没有办法设置批量下载,因此我只是尝试遍历一组对象并触发每个对象的下载。它可以工作,但如果列表包含多个项目,它会随机开始失火。例如,如果我动态创建的列表中有14个项目,则将下载12个项目,而其他2个项目甚至未尝试过。请求消失了。在我的测试中,我添加了一个sleep(1)计时器,然后触发并下载了所有14个计时器,所以我猜测我压倒了下载请求,除非我放慢速度,否则它们会被丢弃。减慢它并不理想...也许还有另一种方式?这是代码:
- (IBAction)downloadAllPics:(UIBarButtonItem *)sender {
if (debug==1) {
NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
}
CoreDataHelper *cdh =
[(AppDelegate *)[[UIApplication sharedApplication] delegate] cdh];
// for loop iterates through all of the items in the tableview
for (Item *item in self.frc.fetchedObjects) {
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *downloadingFilePath1 = [NSString stringWithFormat:@"%@/%@@2x.jpg",docDir, item.imageName];
NSURL *downloadingFileURL1 = [NSURL fileURLWithPath:downloadingFilePath1];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
if ([fileManager fileExistsAtPath:downloadingFilePath1]) {
fileAlreadyExists = TRUE;
if (![fileManager removeItemAtPath:downloadingFilePath1
error:&error]) {
NSLog(@"Error: %@", error);
}
}
__weak typeof(self) weakSelf = self;
self.downloadRequest1 = [AWSS3TransferManagerDownloadRequest new];
self.downloadRequest1.bucket = S3BucketName;
// self.downloadRequest1.key = S3KeyDownloadName1;
self.downloadRequest1.key = [NSString stringWithFormat:@"images/%@@2x.jpg", item.imageName];
self.downloadRequest1.downloadingFileURL = downloadingFileURL1;
self.downloadRequest1.downloadProgress = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite){
// update progress
dispatch_sync(dispatch_get_main_queue(), ^{
weakSelf.file1AlreadyDownloaded = totalBytesWritten;
weakSelf.file1Size = totalBytesExpectedToWrite;
});
};
// this launches the actual S3 transfer manager - it is successfully launched with each pass of loop
[self downloadFiles];
}
[cdh backgroundSaveContext];
}
启动downloadFiles方法:
- (void) downloadFiles {
//if I add this sleep, all 14 download. If I don't usually 11-13 download.
sleep(1);
AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
__block int downloadCount = 0;
[[transferManager download:self.downloadRequest1] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id(BFTask *task) {
if (task.error != nil){
if(task.error.code != AWSS3TransferManagerErrorCancelled && task.error.code != AWSS3TransferManagerErrorPaused){
NSLog(@"%s Errorx: [%@]",__PRETTY_FUNCTION__, task.error);
}
} else {
self.downloadRequest1 = nil;
}
return nil;
}];
}
必须有一种从Amazon S3存储桶下载动态文件列表的方法,对吧?也许有一个传输管理器允许一组文件而不是单独执行它们?
感谢任何和所有帮助。 扎克
答案 0 :(得分:0)
听起来像请求超时间隔设置问题。
首先,配置AWSServiceConfiguration *configuration = ...
时尝试配置timeoutIntervalForRequest
属性。另外,maxRetryCount
也是如此。如果下载每个操作失败,maxRetryCount
将尝试下载。
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:DefaultServiceRegionType
credentialsProvider:credentialsProvider];
[configuration setMaxRetryCount:2]; // 10 is the max
[configuration setTimeoutIntervalForRequest:120]; // 120 seconds
其次,对于下载多个项目,尝试将每个AWSTask
收集到一个数组中,并在组操作结束时获得结果。前)
// task collector
NSMutableSet *uniqueTasks = [NSMutableSet new];
// Loop
for (0 -> numOfDownloads) {
AWSS3TransferManagerDownloadRequest *downloadRequest = [AWSS3TransferManagerDownloadRequest new];
[downloadRequest setBucket:S3BucketNameForProductImage];
[downloadRequest setKey:filename];
[downloadRequest setDownloadingFileURL:sourceURL];
[showroomGroupDownloadRequests addObject:downloadRequest];
AWSTask *task = [[AWSS3TransferManager defaultS3TransferManager] download:downloadRequest];
[task continueWithBlock:^id(AWSTask *task) {
// handle each individual operation
if (task.error == nil) {
}
else if (task.error) {
}
// add to the tasks
[uniqueTasks addObject:task];
return nil;
}
[[AWSTask taskForCompletionOfAllTasks:tasks] continueWithBlock:^id(AWSTask *task) {
if (task.error == nil) {
// all downloads succeess
}
else if (task.error != nil) {
// failure happen one of download
}
return nil;
}];
答案 1 :(得分:0)
某些请求似乎消失的原因是您将AWSS3TransferManagerDownloadRequest
定义为属性。 self.downloadRequest1 = nil;
在后台线程上执行,执行[transferManager download:self.downloadRequest1]
时,self.downloadRequest1
可能是nil
。
您应该删除该属性,只需传递AWSS3TransferManagerDownloadRequest
的实例作为- downloadFiles:
的参数。