产品文档 / 历史记录与验收范围以文中日期为准
新工程迁移说明(2026-10-01):本文记录旧版设计或旧工程历史状态。当前实现以
ZipHarbor/ZipHarbor.xcodeproj为准,参见 迁移映射、新架构 和 最终验收报告。
压缩解压缩 iOS App 技术方案文档
文档版本:v1.0
目标:在一个完整版本中交付稳定、可维护、隐私优先的压缩解压缩工具。
推荐技术栈:Swift、SwiftUI、必要位置使用 UIKit、Swift Concurrency、Document Picker 和 File Provider。建议最低支持 iOS/iPadOS 17,以覆盖所需的 SwiftUI 导航、照片选择、Shortcuts 和多窗口能力,并降低系统兼容分支数量。
1. 技术目标与约束
技术目标
- 支持本地文件、iCloud Drive 和第三方 File Provider。
- 支持大文件和大目录的流式处理。
- 压缩和解压任务可观察、可取消、可恢复。
- 不把文件内容、密码、文件名和路径上传到服务器。
- 对异常压缩包安全失败,不让 App 崩溃或越权写入。
- iPhone、iPad、深色模式、VoiceOver、键盘和拖拽统一支持。
关键约束
- iOS 沙盒不能直接访问任意路径,外部文件必须经安全作用域 URL 或系统文件选择器授权。
- iOS 后台执行时间有限,长任务必须支持检查点和恢复,不能依赖应用长期驻留后台。
- 解压第三方格式需要评估库的许可证、RAR/7z 商用分发限制和 App Store 合规性。
- 云端文件可能是占位文件,读取前需要等待 File Provider 下载完成。
- 压缩包解析属于不可信输入,必须隔离解析、校验路径并限制资源使用。
2. 总体架构
采用分层架构,UI、任务编排、文件系统和压缩引擎相互隔离:
- SwiftUI / UIKit:界面和系统交互。
- Presentation Layer:ViewModel、导航、权限、任务展示。
- Application Layer:导入、归档、解压、任务、预览和分享用例。
- Domain Layer:归档条目、任务、解压计划、冲突策略等业务模型。
- Infrastructure Layer:文件访问、File Provider、归档引擎、预览、持久化、Keychain 和日志。
推荐模块:
- AppShell
- ArchiveUI
- FileBrowser
- TaskCenter
- ArchiveApplication
- ArchiveDomain
- ArchiveEngine
- FileAccess
- Preview
- Persistence
- Security
- ShareIntegration
2.1 模块职责
AppShell
- App 生命周期、场景和窗口管理。
- iPhone Tab、iPad Split View、深色模式和语言环境。
- 启动时恢复未完成任务。
ArchiveUI / FileBrowser
- 文件列表、归档目录、搜索、排序、多选。
- 只通过 ViewModel 访问用例,不直接调用压缩库。
ArchiveApplication
提供用户用例:
- ImportArchiveUseCase
- InspectArchiveUseCase
- ExtractArchiveUseCase
- CreateArchiveUseCase
- PreviewEntryUseCase
- MoveCopyDeleteUseCase
- ShareOutputUseCase
- RetryJobUseCase
每个用例负责参数校验、权限生命周期、任务创建和结果映射,不负责具体压缩算法。
ArchiveDomain
定义与具体库无关的模型和规则。例如:
- ArchiveDescriptor:归档标识、来源、格式、压缩大小、展开大小、条目数、加密信息。
- ArchiveEntry:相对路径、类型、压缩大小、展开大小、修改时间、加密状态。
- ExtractionPlan:来源、所选条目、目标位置、目录结构策略和冲突策略。
- CreateArchiveRequest:来源条目、输出格式、压缩级别、加密选项和目标位置。
- ArchiveJob:任务类型、状态、进度、检查点、结果和错误。
2.2 归档引擎适配层
通过 ArchiveEngine 协议隔离第三方库。协议负责检查归档、异步列出条目、解压、创建和校验。每种库通过 Adapter 实现统一接口。
ZIP 可优先评估 AppleArchive、ZIPFoundation 或 minizip;TAR/GZIP/BZ2 可评估 libarchive;7z 和 RAR 需额外审核组件许可证与商用分发约束。
UI 和业务用例不依赖具体引擎实现。替换或升级库时,归档目录模型和任务界面保持稳定。
2.3 FileAccess
统一处理:
- UIDocumentPickerViewController / SwiftUI 文件导入导出。
- 安全作用域 URL 的 start/stop access 生命周期。
- 文件协调和 NSFileCoordinator。
- File Provider 占位文件下载。
- 临时目录、磁盘空间和文件属性。
- 重名、移动、复制、删除和回收站。
所有 File URL 进入领域层前转换为 FileReference,避免把失效的裸路径传到任务中。
2.4 Persistence
建议使用 SQLite 或 Core Data 保存:
- 最近文件索引。
- 任务及任务检查点。
- 用户设置和冲突策略。
- 收藏和本地标签。
- 常用压缩/解压方案(格式、级别、目标位置、冲突策略;不包含密码)。
- 回收站索引。
不保存压缩包密码明文、文件内容或完整文件名和路径的分析副本。
密码如用户明确启用“保存密码”,使用 Keychain,并按源文件安全标识加密关联。
3. 任务执行设计
3.1 状态机
状态依次为:
创建 → 排队 → 获取输入 → 检查归档 → 准备处理 → 处理中 → 校验 → 完成/部分完成/失败/取消。
需要密码时进入等待密码状态;暂停后可恢复到处理中。任务状态必须持久化。App 被系统杀死后,根据检查点恢复或安全标记为“需要重试”。
3.2 并发策略
- 默认单任务执行,避免同时读写大量文件导致内存、磁盘和电量压力。
- 多任务队列可以排队,用户手动启用时最多并发两个轻量任务。
- 预览和目录读取采用异步流,不阻塞压缩任务。
- UI 通过 AsyncSequence 接收条目和进度更新。
3.3 进度计算
同时维护已处理字节/总字节、已完成条目/总条目、当前速度和滑动平均速度、预计剩余时间。
未知展开大小时显示已处理条目和字节,不伪造百分比。压缩包索引无法提供可靠大小时,使用“正在处理”而不是跳动的错误进度。
3.4 取消和恢复
- 每个任务拥有 CancellationHandler。
- 安全检查点位于条目边界和输出文件 flush 后。
- 取消时清理未完成的临时文件。
- 已完成文件写入原子临时文件后再移动到目标位置。
- 恢复时校验已完成文件大小和校验和,避免重复或损坏。
3.5 后台执行
- 用户启动的压缩任务使用 beginBackgroundTask 为正在执行的短时任务争取收尾时间,并在系统到期回调中及时保存检查点。
- 不依赖 BGProcessingTaskRequest 保证继续用户当前任务;该 API 只用于系统允许时执行后台维护、索引或恢复检查。
- 后台执行不保证立即获得时间,UI 必须允许任务稍后恢复,并准确显示上次保存的任务状态。
- 不在后台上传文件,不依赖自建服务器。
4. 文件和归档安全
4.1 路径安全
解压前对每个条目进行:
- Unicode 规范化。
- 分隔符和点路径清理。
- 生成目标 URL 后验证其标准化路径仍位于目标目录内。
- 拒绝绝对路径、路径穿越、危险符号链接和设备文件。
- 对过长文件名和非法字符采用明确的安全重命名,并记录结果。
路径验证必须使用标准化后的文件 URL 及文件系统组件比较,不能只用字符串前缀判断(例如 /safe 和 /safe-evil 的前缀关系)。
4.2 解压炸弹和资源限制
设置可配置的安全阈值:
- 最大条目数。
- 最大目录深度。
- 最大单文件展开大小。
- 最大总展开大小。
- 压缩比异常阈值。
超过限制时先提示用户;只有用户明确确认且磁盘空间足够才继续。对可疑归档采取保守默认值,避免因极高压缩比占满设备。
4.3 密码和加密
- 密码仅存在于内存中的短生命周期对象。
- 不进入日志、崩溃报告、通知、URL 或分析事件。
- 密码输入页面支持显示/隐藏和 Keychain 读取。
- AES-256 创建和解压需要使用经过审核的实现。
- 错误密码与损坏归档要尽量区分,避免让用户重复尝试无关操作。
4.4 不可信解析
- 压缩库运行在独立模块,解析失败通过领域错误类型返回。
- 对异常输入执行 fuzz 测试。
- 统一捕获底层库错误,不把 C/C++ 异常直接传播到 UI。
- 任何库升级都重新执行格式兼容和安全回归测试。
5. iOS 系统集成
5.1 Files 和 Document Picker
- 使用 UIDocumentPickerViewController 选择输入和目标位置。
- 使用 UTType 声明支持的压缩文件类型和导出类型。
- 使用安全作用域书签记录用户明确授权过的位置。
- 导出时使用系统保存面板,而不是默认复制到 App 私有目录。
5.2 分享面板
实现 Share Extension 或标准 UIActivityViewController 集成:
- 接收压缩文件直接打开归档详情。
- 接收多个普通文件进入创建压缩包流程。
- 分享压缩包和解压结果到其他 App。
- 不在 Extension 中执行长时间压缩,必要时交给主 App 任务队列。
5.3 照片选择
- 使用 PHPickerViewController 或 PhotosPicker。
- 默认只获取用户选择的照片和视频,不请求完整照片库权限。
- 保留原始文件名、扩展名和必要元数据。
- 读取失败的资源在结果页单独列出,不阻塞其他照片。
5.4 iPad
- 使用 NavigationSplitView 或 UIKit 多栏导航。
- 支持多窗口、拖放、键盘快捷键、指针和横屏。
- 预览与归档目录并排展示,任务中心使用侧栏或浮层。
5.5 App Intents 和 Shortcuts
- 提供打开压缩包、创建 ZIP、查看进行中任务等意图。
- 通过系统文件选择输入,遵守用户授予的文件访问范围。
- Shortcut 不绕过密码输入、冲突确认和安全阈值等必要交互。
- 批处理可以返回任务标识和完成状态;需要用户决策时将控制权交回 App。
6. 预览系统
预览层独立于压缩引擎:
- 引擎以流或临时文件提供条目内容。
- Preview Provider 根据 UTType 选择 Quick Look、系统 PDF、图片或媒体播放器。
- 大文件优先流式预览,不默认复制完整文件。
- 无法预览时提供“导出到其他 App”,不显示空白页。
支持图片、PDF、TXT、RTF、Office 常见格式以及常见音视频的只读预览。预览失败不应影响条目导出。
7. 错误模型
定义稳定的领域错误,不直接把底层错误字符串展示给用户:
- unsupportedFormat
- invalidArchive
- incorrectPassword
- missingVolume
- insufficientStorage(required, available)
- unsafePath
- fileProviderUnavailable
- permissionDenied
- cancelled
- partialFailure
每个错误映射到用户能理解的标题、原因说明、一个首选下一步动作,以及可选的技术详情(仅用于用户主动反馈和调试)。
8. 性能方案
- 使用分块流式读写,默认块大小通过基准测试确定。
- 目录读取采用增量流和虚拟化列表。
- 输出先写入临时文件,完成后原子移动。
- 对照片和视频不做重复内存拷贝。
- 大文件计算校验和时使用后台任务和进度上报。
- 在任务启动前检查磁盘空间,处理云端下载空间和输出空间的双重需求。
- 使用 Instruments 检查内存峰值、文件句柄、I/O 等待、CPU 和电量。
建议基准场景:
| 场景 | 目标 |
|---|---|
| 100 MB ZIP 目录展示 | 5 秒内显示首屏条目 |
| 1 GB ZIP 解压 | 内存不随总文件大小线性增长 |
| 10,000 条目目录 | 列表滚动无明显卡顿 |
| 100 张照片压缩 | UI 可操作,任务可取消 |
| 云端占位文件 | 下载、解压、输出状态清晰 |
9. 测试方案
9.1 单元测试
- 格式识别和扩展名不一致。
- 相对路径规范化。
- 冲突策略。
- 空间估算和进度计算。
- 任务状态机和恢复检查点。
- 错误映射和本地化文案键。
9.2 集成测试
- Files 导入、导出和安全作用域生命周期。
- 分享面板接收单个和多个文件。
- iCloud 和第三方 File Provider。
- 照片选择器和大批量资源。
- Face ID、通知、深色模式、动态字体。
9.3 归档兼容测试
建立固定 fixture 集合:
- ZIP Store、Deflate、Zip64、传统密码、AES。
- RAR 常见版本和密码包。
- 7z 常见压缩算法和密码包。
- TAR/GZIP/BZ2/TGZ/ZIPX。
- 多卷、嵌套目录、Unicode 文件名、emoji、长路径。
- 损坏中央目录、截断文件、错误扩展名和恶意路径。
每个 fixture 验证目录、文件大小、校验和、权限、错误类型和 UI 结果。
9.4 安全测试
- Zip Slip 和绝对路径写入。
- 解压炸弹和资源耗尽。
- 符号链接、硬链接和特殊文件。
- 密码出现在日志、崩溃报告、通知或分析中的扫描。
- 第三方库 fuzz 测试。
- 沙盒越权和安全作用域泄漏。
9.5 UI 自动化和可用性测试
验证分享面板到解压完成、多选照片到 ZIP 完成、密码错误、重名、空间不足、网络断开、取消和恢复等完整流程,并覆盖 iPhone 小屏、iPad 横屏、深色模式、Dynamic Type 和 VoiceOver。
首次使用测试目标:用户在 60 秒内完成打开 ZIP 并保存文件。
10. 隐私、日志和可观测性
隐私原则
- 不上传文件内容、文件名、路径、密码和云盘列表。
- 统计只记录匿名任务类型、格式、耗时区间、成功/失败类别和 App 版本。
- 用户可以关闭分析和通知。
- App Store 隐私标签与实际代码保持一致。
日志原则
- 默认只记录错误类型、库错误码、任务 ID 和版本信息。
- 文件名、路径、密码使用脱敏占位符或完全省略。
- 用户主动反馈时,提供可选诊断包,不自动上传文件。
- 生产日志分级,避免大量目录条目污染控制台。
11. 依赖、许可证和发布
在引入压缩库前完成:
- 对 ZIP、RAR、7z、TAR/GZIP 的覆盖率评估。
- 商用分发和 App Store 的许可证审核。
- 静态链接、动态链接和第三方声明页面确认。
- 库升级策略和安全通告订阅。
- 二进制大小、启动时间和隐私清单审核。
发布前检查:
- 所有支持格式 fixture 通过。
- 无已知路径穿越和资源耗尽问题。
- 崩溃、内存、文件句柄和电量基准通过。
- Files、分享、照片、通知和 Face ID 权限文案通过。
- App Store 隐私标签、支持 URL、隐私政策和许可证页完整。
- 免费基础流程没有广告或强制订阅阻断。
12. 推荐目录结构
ZipApp/ - App/ - Features/ - Files/ - ArchiveDetail/ - CreateArchive/ - TaskCenter/ - Settings/ - Domain/ - Models/ - Errors/ - Policies/ - Application/ - UseCases/ - TaskCoordinator/ - Infrastructure/ - ArchiveEngine/ - FileAccess/ - Persistence/ - Preview/ - Security/ - ShareExtension/ - Resources/ - Localizations/ - Fixtures/ - Tests/ - UnitTests/ - IntegrationTests/ - ArchiveFixtureTests/ - SecurityTests/ - UITests/
13. 最终技术决策
- 产品采用本地优先架构,不建设文件上传后端。
- 所有压缩库通过 ArchiveEngine 适配层接入,避免 UI 和第三方库耦合。
- 所有任务使用持久化状态机、流式 I/O 和原子输出。
- 所有外部文件通过 Files、Share、Photos 系统入口获得,不扫描用户整个设备。
- 先保证 ZIP、RAR、7z 的稳定性,再扩展更多格式;不为了格式数量牺牲安全和可靠性。
- 通过功能边界控制复杂度,OCR、PDF 编辑、视频转换、浏览器和自建云盘不进入产品。
14. 本次实现对齐说明
当前工程位于 app/,产品名称为 ZipHarbor,最低支持 iOS 17,使用 SwiftUI、SwiftData 和 libarchive.xcframework。
已实现的主链路(运行验证状态见验收报告):
- Files / 分享面板导入归档到本地库,支持最近列表、收藏、搜索和中英文资源。
- ZIP、7z、RAR、TAR、GZIP、BZIP2 的归档读取;RAR 仅读取,检测到加密 RAR 时给出明确边界提示。
- ZIP AES-256 创建、密码读取和错误密码重试;7z 创建保持为普通归档,7z 密码创建在当前 libarchive XCFramework 中不可用,页面会明确引导使用 ZIP AES。
- 选择性解压、保留目录、重名策略、原子临时文件输出、路径穿越阻断。
- ZIP
.zip.001卷组导入与重组;创建端可按 64/128/256/512 MB 生成 ZIP 切片并分享卷组。 - SwiftData 任务历史、进度更新、错误状态、Face ID/设备密码应用锁和深色外观。
有意保持边界的能力:RAR/7z 归档创建以 libarchive 支持为准;不把密码写入历史;暂停/系统杀死后的检查点恢复、通知、快捷指令、回收站和完整的文件管理器仍需要单独补齐,不能从当前版本的界面开关推断为已交付。
14.1 验证记录(2026-09-30)
模拟器 ZipHarborTests 7/7、ZipHarborUITests 1/1 已通过;simctl 安装并启动应用成功,截图保存在 docs/iphone14-home-final.png。测试期间出现过 iOS 26.5 Accessibility 运行时警告,但最终 UI 流程完成。
实体 iPhone 14(UDID IPHONE14_UDID)已完成安装、启动和 ZipHarborTests 7/7 真机验证,截图保存在 docs/iphone14-real-home-final.png。真机 UI runner 在开启自动化模式时超时,报 Timed out while enabling automation mode,需要稳定的设备自动化环境后补跑 UI 页面断言。