Swift/SwiftUI 原生 iPad 应用 —— 支持 6 类漫画格式、日漫右翻、跨卷连读,完全离线零收集。

Koma 是一款我从解压引擎到 App Store 素材全部独立完成的 iPad 专用漫画阅读器。通过文件魔数识别打开 CBZ、CBR、CB7、CBT、PDF 和图片型 EPUB,支持日漫右翻与真正的双页跨页排版,卷与卷之间无缝连读,且完全不联网 —— 零追踪、零数据收集。
我想要一个像 Apple Books 对待书那样对待漫画的阅读器:打开你手上已有的文件,记住读到哪里,然后把自己藏起来。商店里的多数阅读器要么强制云账号,要么书架上贴满广告,要么根本处理不好日漫的右翻。Koma 从设计上就是完全离线的 —— 隐私清单里声明零追踪、数据收集列表为空,因为确实没有任何东西可以声明。文件通过 security-scoped bookmark 就地打开,你的书库不会被复制或上传到任何地方。
Koma 能打开六种格式 —— CBZ/ZIP、CBR(RAR)、CB7(7z)、CBT(TAR)、PDF 和图片型 EPUB —— 外加普通图片文件夹。其中 ZIP 和 TAR 解压器完全自研;PDF 通过 PDFKit 按需矢量渲染,EPUB 按 OPF spine 解析,页序以此为准。只有 RAR 和 7z 引入了库(Unrar.swift 和 SWCompression),因为这两种算法没有自写的道理。所有文件都靠魔数而非后缀识别 —— 后缀写错的压缩包照样能打开。并且永远不整包解压:页面按需逐张解出来。
翻页模式基于 UIPageViewController,保留系统级、可中断的翻页手感,同时支持日漫右翻和欧美左翻。导入时 Koma 用部分解压探测每页尺寸 —— 亚秒级完成,不用解开整个压缩包 —— 因此跨页大图提前可知,双页模式下独占一屏,还有「装订」开关处理封面单独成页时的配对错位。读完一卷,下一卷自动接上;在第一页往回翻,落在上一卷的最后一页。条漫模式则是独立的 UICollectionView 路径:高度从尺寸缓存预知,图片加载永远不会引起布局跳动。
漫画扫图很大 —— 一张 2000×3000 的页面如果朴素解码,还没上屏就要吃掉约 24 MB 内存。Koma 通过 ImageIO 直接降采样到目标尺寸,同一页只占几 MB,真正放大时才解码高分辨率版本。页面缓存是带真实字节预算的 NSCache(物理内存的五分之一),收到内存警告立即清空。小细节也保持同样的用心:放大状态下翻页有橡皮筋阻力,条漫模式纵向滑动可以压暗亮度。
界面刻意做成单色:浅色模式是暖纸白,暗色模式是炭墨色,用发丝细线做层次,导航标题用衬线体 —— 书的 App 该有一点书卷气。彩色只留给语义 —— 仅用于警告和破坏性操作。阅读器工具栏是悬浮的圆角胶囊,而不是通栏铺满:漫画永远是主角,界面只是短暂来访的客人。阅读页面本身在两种模式下都保持纯黑。应用内置四种语言的使用手册(English、日本語、简体中文、繁體中文)—— 以漫画格式的 CBZ 呈现,首次启动时自动出现在书架上。
约 5,800 行 Swift 5.10 代码,iPad 专用,iOS 17+。书架和库用 SwiftUI;手感关键的地方交给 UIKit —— 翻页阅读用 UIPageViewController,条漫滚动用 UICollectionView —— 工具栏再以 SwiftUI 浮层盖回来。状态管理用 iOS 17 的 @Observable,工程由纳入版本控制的 project.yml 经 xcodegen 生成,单元测试覆盖解压后端、文件名解析、双页布局和翻页方向。App Store 材料齐备:隐私清单、字符串目录(英文和日文界面)、以及整套 2064×2752 营销截图。