目录下载

最近更新时间:2025-12-30 18:01:42

我的收藏

简介

本文档提供关于目录下载的接口说明以及 SDK 示例代码,支持递归下载整个目录树,包括所有子目录和文件。该功能具有以下特点:
递归下载:自动遍历并下载目录中的所有子目录和文件。
任务管理:支持启动、暂停、恢复、取消等完整的任务生命周期管理。
进度跟踪:实时监控下载进度和状态变化。
冲突处理:支持多种文件冲突策略(询问、重命名、覆盖)。
数据持久化:任务信息自动保存到数据库,支持应用重启后恢复。
查询过滤:支持按状态、类型、排序等多种条件查询任务。
注意:
回调线程:回调在后台线程执行,更新 UI 时需要切换到主线程。
错误处理:下载失败时,可通过 error 获取详细错误信息。

相关资源

SDK 源码下载请参见 smh-sdk-ios

初始化

在应用启动后,通过 QCloudSMHService 的 setupDownload 方法初始化目录下载的功能。
#import "QCloudSMHService+FolderDownload.h"

- (BOOL)application:(UIApplication * )application
didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {
// 初始化目录下载
[[QCloudSMHService defaultSMHService] setupDownload];
// 更新目录下载配置(主要是缓存池的容量)
// 缓存池的容量的上限决定了内存中存放任务的数量,如果设备性能比较好可以适当提升容量
// 正常情况使用默认配置即可
// 可选配置
QCloudSMHTaskManagerConfig *config = [[QCloudSMHTaskManagerConfig alloc] init];
// 文件缓存池最大容量,默认为10
config.maxFileCacheSize = 10;
// 目录缓存池最大容量,默认为10
config.maxFolderCacheSize = 10;

[[QCloudSMHService defaultSMHService] updateDownloadFolerConfig:config];
return YES;
}
注意:
强烈建议在应用初始化的时候进行配置。
如果后续不再使用文件夹下载功能可以使用 - (void)teardownDownload 来解除相关的功能。

创建任务

通过初始化一个 QCloudSMHDownloadRequest 来创建一个目录下载的请求。
#import "QCloudSMHService+FolderDownload.h"

// 创建一个目录下载请求
QCloudSMHDownloadRequest *request = [[QCloudSMHDownloadRequest alloc]
initWithLibraryId:self.libraryId // 媒体库 ID
spaceId:self.spaceId // 租户空间 ID
userId:self.userId // 用户 ID
path: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 // 媒体库ID
spaceId:self.spaceId // 租户空间ID
userId:self.userId // 用户ID
path:remotePath // 目录的远程路径
type:QCloudSMHTaskTypeFolder // 下载类型
localURL:localURL]; // 目录的保存路径

// 发起下载请求
[[QCloudSMHService defaultSMHService] downloadFolder:request];


监听下载状态和进度

通过 QCloudSMHService 中的 observerFolderDownloadForRequest 方法监听下载任务的状态和进度。
#import "QCloudSMHService+FolderDownload.h"

NSError *error = nil;

// 监听当前下载的目录/文件
BOOL result = [[QCloudSMHService defaultSMHService] observerFolderDownloadForRequest:request
error:&error
progress:^(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 // 媒体库ID
spaceId:self.spaceId // 租户空间ID
userId:self.userId // 用户ID
path:remotePath // 目录的远程路径
type:QCloudSMHTaskTypeFolder // 下载类型
localURL:localURL]; // 目录的保存路径


// 监听当前下载的目录/文件
BOOL result = [[QCloudSMHService defaultSMHService] observerFolderDownloadForRequest:request
error:&error
progress:^(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 // 媒体库ID
spaceId:self.spaceId // 租户空间ID
userId:self.userId // 用户ID
path: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 // 媒体库ID
spaceId:self.spaceId // 租户空间ID
userId:self.userId // 用户ID
path: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:request
page:@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 // 媒体库ID
spaceId:self.spaceId // 租户空间ID
userId:self.userId // 用户ID
path:remotePath // 目录的远程路径
type:QCloudSMHTaskTypeFolder // 下载类型
localURL:localURL]; // 目录的保存路径

// 会查询当前request指定目录下载的所有子文件和子目录

NSArray<QCloudSMHDownloadDetail *> *allTasks = [[QCloudSMHService defaultSMHService]
getFolderDownloadDetails:request
page:@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 // 媒体库ID
spaceId:self.spaceId // 租户ID
userId:self.userId // 用户空间ID
path: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 // 媒体库ID
spaceId:self.spaceId // 租户空间ID
userId:self.userId // 用户ID
path: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 // 媒体库ID
spaceId:self.spaceId // 租户空间ID
userId:self.userId // 用户ID
path:remotePath // 目录的远程路径
type:QCloudSMHTaskTypeFolder // 下载类型
localURL:localURL]; // 目录的保存路径
// 发起重启请求
[[QCloudSMHService defaultSMHService] downloadFolder:request];

错误码

错误码
字段
描述
10000
QCloudSMHTaskErrorPathConflict
文件路径冲突
10001
QCloudSMHTaskErrorInternalError
内部错误
10002
QCloudSMHTaskCreateFolderFailed
创建目录失败
10003
QCloudSMHTaskErrorUserCancel
用户取消
10004
QCloudSMHTaskErrorUserDelete
用户删除
说明:
下载过程中,如果收到了错误信息。可以按照上面的错误码进行重试操作或是弹窗提示用户。