简介
本文档提供关于目录下载的接口说明以及 SDK 示例代码,支持递归下载整个目录树,包括所有子目录和文件。该功能具有以下特点:
递归下载:自动遍历并下载目录中的所有子目录和文件。
任务管理:支持启动、暂停、恢复、取消等完整的任务生命周期管理。
进度跟踪:实时监控下载进度和状态变化。
冲突处理:支持多种文件冲突策略(询问、重命名、覆盖)。
数据持久化:任务信息自动保存到数据库,支持应用重启后恢复。
查询过滤:支持按状态、类型、排序等多种条件查询任务。
注意:
回调线程:回调在后台线程执行,更新 UI 时需要切换到主线程。
错误处理:下载失败时,可通过 error 获取详细错误信息。
相关资源
初始化
在应用启动后,通过 QCloudSMHService 的 setupDownload 方法初始化目录下载的功能。
#import "QCloudSMHService+FolderDownload.h"- (BOOL)application:(UIApplication * )applicationdidFinishLaunchingWithOptions:(NSDictionary * )launchOptions {// 初始化目录下载[[QCloudSMHService defaultSMHService] setupDownload];// 更新目录下载配置(主要是缓存池的容量)// 缓存池的容量的上限决定了内存中存放任务的数量,如果设备性能比较好可以适当提升容量// 正常情况使用默认配置即可// 可选配置QCloudSMHTaskManagerConfig *config = [[QCloudSMHTaskManagerConfig alloc] init];// 文件缓存池最大容量,默认为10config.maxFileCacheSize = 10;// 目录缓存池最大容量,默认为10config.maxFolderCacheSize = 10;[[QCloudSMHService defaultSMHService] updateDownloadFolerConfig:config];return YES;}
注意:
强烈建议在应用初始化的时候进行配置。
如果后续不再使用文件夹下载功能可以使用
- (void)teardownDownload 来解除相关的功能。创建任务
通过初始化一个 QCloudSMHDownloadRequest 来创建一个目录下载的请求。
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库 IDspaceId:self.spaceId // 租户空间 IDuserId:self.userId // 用户 IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 可选参数request.enableResumeDownload = YES; // 是否开启断点续传(默认开启)request.enableCRC64Verification = YES; // 是否开启单个文件的CRC64校验(默认开启)request.conflictStrategy = QCloudSMHConflictStrategyEnumOverWrite; // 本地保存路径冲突策略(默认为覆盖)
参数说明
参数名称 | 描述 | 类型 |
libraryId | 媒体库 ID | NSString |
spaceId | 存储空间 ID | NSString |
userId | 用户 ID | NSString |
remotePath | 云端目录路径,例如 "/documents/project" | NSString |
type | 下载的类型: 文件:QCloudSMHTaskTypeFile 目录:QCloudSMHTaskTypeFolder | QCloudSMHTaskType |
localURL | 目录的保存路径 注意: 模拟器下需要将保存目录放到 Documents 下。 | NSURL |
enableResumeDownload | 是否启用文件的断点续传(默认开启) | BOOL |
enableCRC64Verification | 是否启用 CRC64 校验(默认开启) | BOOL |
conflictStrategy | 文件冲突时的处理策略,取值如下: QCloudSMHConflictStrategyEnumAsk:冲突时抛出异常 QCloudSMHConflictStrategyEnumRename:自动重命名 QCloudSMHConflictStrategyEnumOverwrite:覆盖已存在的文件(默认) | QCloudSMHConflictStrategyEnum |
开始下载
通过 QCloudSMHService 的 downloadFolder 来发起一个下载请求。
#import "QCloudSMHService+FolderDownload.h"// 发起下载请求[[QCloudSMHService defaultSMHService] downloadFolder:request];
参数说明
参数名称 | 描述 | 类型 |
request | 下载请求 | QCloudSMHDownloadRequest |
示例代码
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库IDspaceId:self.spaceId // 租户空间IDuserId:self.userId // 用户IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 发起下载请求[[QCloudSMHService defaultSMHService] downloadFolder:request];
监听下载状态和进度
通过 QCloudSMHService 中的 observerFolderDownloadForRequest 方法监听下载任务的状态和进度。
#import "QCloudSMHService+FolderDownload.h"NSError *error = nil;// 监听当前下载的目录/文件BOOL result = [[QCloudSMHService defaultSMHService] observerFolderDownloadForRequest:requesterror:&errorprogress:^(NSString *path, QCloudSMHTaskType type,int64_t bytesProcessed, int64_t totalBytes,int completedFiles, int totalFiles) {NSLog(@"📊 进度更新 - %@ [%lld/%lld bytes] [%d/%d files]",path, bytesProcessed, totalBytes, completedFiles, totalFiles);}stateChanged:^(NSString *path, QCloudSMHTaskType type,QCloudSMHTaskState state, NSError *error) {NSLog(@"📡 状态变化 - %@ -> %ld %@", path, (long)state, error ?: @"");}];
说明:
建议每次监听的目录/文件数量不超过一屏。
监听逻辑一定要放到下载逻辑之前,避免丢失一部分进度。
每个下载任务只能监听一次,如果重复监听会覆盖之前的监听者。
参数说明
参数名称 | 描述 | 类型 |
request | 下载请求 | QCloudSMHDownloadRequest |
error | 若监听失败,error 里会包含失败原因 | NSError |
progress | 进度回调 | QCloudSMHFolderProgressCallback |
stateChanged | 状态回调 | QCloudSMHFolderStateChangedCallback |
QCloudSMHFolderProgressCallback 回调参数说明
参数名称 | 描述 | 类型 |
path | 云端目录路径,例如 "/documents/project" | String |
type | 正在监听的下载类型: 文件:QCloudSMHTaskTypeFile 目录:QCloudSMHTaskTypeFolder | QCloudSMHTaskType |
bytesProcessed | 目录:已经下载的字节数(包含子目录) 文件:已经下载的字节数 | int64_t |
totalBytes | 目录:总的字节数(包含子目录) 文件:总的字节数 | int64_t |
completedFiles | 目录:已经下载的文件数量(包含子目录) 文件:已经下载的文件数量(下载完成后是1,其余情况是0) | int |
totalFiles | 目录:总的文件数(包含子目录) 文件:总的文件数(默认为1) | int |
QCloudSMHFolderStateChangedCallback 回调参数说明
参数名称 | 描述 | 类型 |
path | 云端目录路径,例如 "/documents/project" | String |
type | 下载类型: 文件:QCloudSMHTaskTypeFile 目录:QCloudSMHTaskTypeFolder | QCloudSMHTaskType |
state | 目录/文件的下载状态: 空闲:QCloudSMHTaskStateIdle 扫描中:QCloudSMHTaskStateScanning(仅目录) 下载中:QCloudSMHTaskStateDownloading 已暂停:QCloudSMHTaskStatePaused 已完成:QCloudSMHTaskStateCompleted 失败:QCloudSMHTaskStateFailed | QCloudSMHTaskState |
error | 下载失败时包含错误详情,成功时为nil | NSError |
返回结果说明
返回 BOOL 值,表示监听是否成功。
示例代码
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库IDspaceId:self.spaceId // 租户空间IDuserId:self.userId // 用户IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 监听当前下载的目录/文件BOOL result = [[QCloudSMHService defaultSMHService] observerFolderDownloadForRequest:requesterror:&errorprogress:^(NSString *path, QCloudSMHTaskType type,int64_t bytesProcessed, int64_t totalBytes,int completedFiles, int totalFiles) {NSLog(@"📊 进度更新 - %@ [%lld/%lld bytes] [%d/%d files]",path, bytesProcessed, totalBytes, completedFiles, totalFiles);}stateChanged:^(NSString *path, QCloudSMHTaskType type,QCloudSMHTaskState state, NSError *error) {NSLog(@"📡 状态变化 - %@ -> %ld %@", path, (long)state, error ?: @"");}];if (result) {// 发起下载请求[[QCloudSMHService defaultSMHService] downloadFolder:request];} else {NSLog(@"监听异常:%@", error);}
移除下载状态和进度监听
通过 QCloudSMHService 中的 removeObserverFolderDownloadForRequest 方法移除下载任务的状态和进度。
#import "QCloudSMHService+FolderDownload.h"[[QCloudSMHService defaultSMHService] removeObserverFolderDownloadForRequest:request];
说明:
如果在 tableView 中监听下载状态和进度,那么强烈建议在
cell display ( - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;)时移除订阅。参数说明
参数名称 | 描述 | 类型 |
request | 下载请求 | QCloudSMHDownloadRequest |
示例代码
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库IDspaceId:self.spaceId // 租户空间IDuserId:self.userId // 用户IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 移除监听[[QCloudSMHService defaultSMHService] removeObserverFolderDownloadForRequest:request];
管理下载
查询任务
获取单个下载信息
通过 QCloudSMHService 中的 getFolderDownloadDetail 获取单个任务的下载详情。
#import "QCloudSMHService+FolderDownload.h"// 获取单个任务的下载详情QCloudSMHDownloadDetail *detail = [[QCloudSMHService defaultSMHService] getFolderDownloadDetail:request];
参数说明
参数名称 | 描述 | 类型 |
request | 下载请求 | QCloudSMHDownloadRequest |
返回结果说明
返回 QCloudSMHDownloadDetail 对象,该对象中包含了下载任务的详细信息。如:下载状态、创建/更新时间、保存路径、下载进度等。
示例代码
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库IDspaceId:self.spaceId // 租户空间IDuserId:self.userId // 用户IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 获取单个任务的下载详情QCloudSMHDownloadDetail *detail = [[QCloudSMHService defaultSMHService] getFolderDownloadDetail:request];
获取下载信息列表
通过 QCloudSMHService 中的 getFolderDownloadDetails 获取当前 remotePath 下的所有子任务的下载信息。
#import "QCloudSMHService+FolderDownload.h"// 会查询当前request指定目录下载的所有子文件和子目录NSArray<QCloudSMHDownloadDetail *> *allTasks = [[QCloudSMHService defaultSMHService]getFolderDownloadDetails:requestpage:@0 // 页码:(从0开始,为nil时表示获取全部)pageSize:@10 // 每页的大小,为nil时表示获取全部orderType:QCloudSMHSortFieldUpdatedAt // 排序字段(创建时间、更新时间)orderDirection:QCloudSMHSortOrderDescending // 排序方向(升序、降序)grouping:QCloudSMHGroupFlat //分组类型:(平铺、按目录/文件分组)directoryFilter:QCloudSMHDirectoryAll // 筛选方式:(仅文件、仅目录、全部)states:nil // 按状态过滤:为nil时查询全部];
参数说明
参数名称 | 描述 | 类型 |
request | 下载请求 | QCloudSMHDownloadRequest |
page | 页码(从0开始,为 nil 时表示获取全部) | NSNumber |
pageSize | 每页的大小(为 nil 时表示获取全部) | NSNumber |
orderType | 排序方式 创建时间 更新时间 | QCloudSMHSortField |
orderDirection | 排序方向 升序 降序 | QCloudSMHSortOrder |
grouping | 分组类型 平铺 按目录/文件分组 | QCloudSMHGroup |
directoryFilter | 筛选方式 仅文件 仅目录 全部 | QCloudSMHDirectory |
states | 查询下载任务的状态(可传递多个状态,如为 nil 时表示查询全部,取值如下: QCloudSMHTaskStateIdle = 0(空闲) QCloudSMHTaskStateScanning(扫描中(仅文件夹任务)) QCloudSMHTaskStateDownloading(下载中) QCloudSMHTaskStatePaused(已暂停) QCloudSMHTaskStateCompleted(已完成) QCloudSMHTaskStateFailed(失败) | NSArray<NSNumber *> |
返回结果说明
返回 QCloudSMHDownloadDetail 对象,该对象中包含了下载任务的详细信息。如:下载状态、创建/更新时间、保存路径、下载进度等。
示例代码
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库IDspaceId:self.spaceId // 租户空间IDuserId:self.userId // 用户IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 会查询当前request指定目录下载的所有子文件和子目录NSArray<QCloudSMHDownloadDetail *> *allTasks = [[QCloudSMHService defaultSMHService]getFolderDownloadDetails:requestpage:@0 // 页码:(从0开始,为nil时表示获取全部)pageSize:@10 // 每页的大小,为nil时表示获取全部orderType:QCloudSMHSortFieldUpdatedAt // 排序字段(创建时间、更新时间)orderDirection:QCloudSMHSortOrderDescending // 排序方向(升序、降序)grouping:QCloudSMHGroupFlat //分组类型:(平铺、按目录/文件分组)directoryFilter:QCloudSMHDirectoryAll // 筛选方式:(仅文件、仅目录、全部)states:nil // 按状态过滤:为nil时查询全部];
暂停任务
通过 QCloudSMHDownloadRequest 中的 pause 方法暂停下载中的任务。
#import "QCloudSMHService+FolderDownload.h"// 暂停下载(如果是目录,会暂停目录下的所有文件和子目录)[request pause];
示例代码
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库IDspaceId:self.spaceId // 租户IDuserId:self.userId // 用户空间IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 暂停下载(如果是目录,会暂停目录下的所有文件和子目录)[request pause];
继续任务
通过 QCloudSMHDownloadRequest 中的 resume 方法继续下载中的任务。
#import "QCloudSMHService+FolderDownload.h"// 继续下载(如果是目录,会继续目录下的所有文件和子目录)[request resume];
示例代码
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库IDspaceId:self.spaceId // 租户空间IDuserId:self.userId // 用户IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 继续下载(如果是目录,会继续目录下的所有文件和子目录)[request resume];
取消任务
通过 QCloudSMHDownloadRequest 中的 cancel 方法取消下载中的任务。
#import "QCloudSMHService+FolderDownload.h"// 取消下载(如果是目录,会取消目录下的所有文件和子目录)[request cancel];
说明:
会删除本地已经下载的临时文件,数据库中的断点信息会被清理。
调用 cancel 方法后如果有监听该任务,则会立即收到下载失败的通知。错误码为:QCloudSMHTaskErrorUserCancel。
示例代码
#import "QCloudSMHService+FolderDownload.h"QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 和父目录保持一致spaceId:self.spaceId // 和父目录保持一致userId:self.userId // 和父目录保持一致path:remotePath // 子目录远端路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 和父目录保持一致// 取消下载(如果是目录,会取消目录下的所有文件和子目录)[request cancel];
删除任务
通过 QCloudSMHDownloadRequest 中的 delete 方法删除下载中的任务。
#import "QCloudSMHService+FolderDownload.h"// 删除下载(如果是目录,会取消目录下的所有文件和子目录)[request delete];
说明:
会删除本地已经下载的临时文件,数据库中的记录也会被删除
调用 delete 方法后如果有监听该任务,则会立即收到下载失败的通知。错误码为:QCloudSMHTaskErrorUserDelete。
示例代码
#import "QCloudSMHService+FolderDownload.h"QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 和父目录保持一致spaceId:self.spaceId // 和父目录保持一致userId:self.userId // 和父目录保持一致path:remotePath // 子目录远端路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 和父目录保持一致// 删除下载(如果是目录,会取消目录下的所有文件和子目录)[request delete];
重启任务
应用重启后,可以通过 QCloudSMHService 中的 downloadFolder 方法恢复数据库中空闲、扫描中以及下载中的任务。
#import "QCloudSMHService+FolderDownload.h"// 发起重启请求[[QCloudSMHService defaultSMHService] downloadFolder:request];
说明:
仅能恢复空闲、扫描中、下载中的任务。对于暂停状态的任务如果需要恢复下载请使用 QCloudSMHDownloadRequest 中的 resume 方法。
对于已经完成、失败的任务,调用该方法会重新开始下载,此前的进度将会丢失。
示例代码
#import "QCloudSMHService+FolderDownload.h"// 创建一个目录下载请求QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]initWithLibraryId:self.libraryId // 媒体库IDspaceId:self.spaceId // 租户空间IDuserId:self.userId // 用户IDpath:remotePath // 目录的远程路径type:QCloudSMHTaskTypeFolder // 下载类型localURL:localURL]; // 目录的保存路径// 发起重启请求[[QCloudSMHService defaultSMHService] downloadFolder:request];
错误码
错误码 | 字段 | 描述 |
10000 | QCloudSMHTaskErrorPathConflict | 文件路径冲突 |
10001 | QCloudSMHTaskErrorInternalError | 内部错误 |
10002 | QCloudSMHTaskCreateFolderFailed | 创建目录失败 |
10003 | QCloudSMHTaskErrorUserCancel | 用户取消 |
10004 | QCloudSMHTaskErrorUserDelete | 用户删除 |
说明:
下载过程中,如果收到了错误信息。可以按照上面的错误码进行重试操作或是弹窗提示用户。