
在 weekly.fatbobman.com 订阅本周报的电子邮件版本。访问我的博客 肘子的 Swift 记事本 查看更多的文章。加入 Discord 社区,与 2000+ 中文开发者深入交流 Swift、SwiftUI 开发体验。
去 Apple Store 修手机
父亲的 iPhone 16 突然无法充电。预约后,我前往 Apple Store 送修。工作人员确认问题后,为我提供了一部 iPhone 14 作为备用机,并协助完成数据转移。十二天后(期间正好赶上一个长假),设备维修完成------更换了 Type-C 接口,同时还免费更换了一块新电池。体验一如既往地令人满意。
这些年来,我修过不少苹果设备。印象较深的几次包括:因"显卡门"事件,MacBook Pro 免费更换主板;2011 款 iMac 27 英寸因屏幕进灰,免费更换显示屏。其他一些小问题,如果时机合适,有时会直接换新设备。
网络上确实不乏关于 Apple Store 或授权维修商的不愉快经历。但就我个人而言,多次维修体验都算顺利------或许得益于对设备问题的充分了解,以及始终保持友好的沟通态度。
一个有趣的观察是:Apple Store 里有相当多的老年用户。与天才吧工作人员闲聊时得知,许多年轻人会把淘汰的 iPhone 或 iPad 送给长辈,或直接购买新设备作为礼物,但往往没有时间教他们使用。于是,天才吧相当一部分工作量,变成了帮助老年人注册账户、安装应用、指导基本操作。
天才吧的存在,让全年龄段用户都能享受科技的便利------既服务了消费者,也增强了品牌的用户粘性。如今许多其他品牌也开设了规模不小的线下门店,但大多仍停留在展示与销售层面。在网购已成主流的时代,实体店的价值早已超越"卖产品",更在于那种人与人面对面交流的温度------这,正是 Apple Store 的重要魅力所在。
近期推荐
SwiftUI 应用热重载方案 (Hot Reloading SwiftUI Apps)
虽然 Xcode Preview 为开发者带来了极大便利,可以即时查看 UI 的变化,但它仍存在不少限制。Daniel Hooper 在本文中展示了一种巧妙的热重载方案:将 UI 与应用逻辑编译为动态库(dynamic library),并由宿主 App 在运行时加载。当代码变更时,重新加载新库并替换旧库。这一方案的亮点在于:支持完整应用运行、可保留状态,不依赖 Xcode。整个实现仅需约 120 行代码,充分体现了"理解原理后,复杂功能也能以简洁方式实现"的魅力。
精通 UITableViewDiffableDataSource
尽管 SwiftUI 的列表能力持续进步,但在大数据量、复杂交互或需要精细控制的场景中,UITableView 依然不可替代。相较于 SwiftUI 的声明式简洁,UITableView 的数据源管理更易出错,批量更新也常因数据与 UI 不一致而崩溃。Kingnight (Jinkai) 通过一个功能完备的音乐播放列表示例,系统讲解了 UITableViewDiffableDataSource 的现代用法。
文章不仅覆盖基础,还深入对比 reconfigureItems
与 reloadItems
的性能取舍,拆解拖拽重排与滑动删除的实现,并通过 BaseReorderableDiffableDataSource 与 DiffableTableAdapter 给出可复用的架构实践。无论是在 SwiftUI 项目中集成 UIKit 列表,还是维护现有 UIKit 项目,这都是一份扎实的现代化指南。
iPhone 17 屏幕尺寸 (iPhone 17 Screen Sizes)
iPhone 17 系列的屏幕配置迎来重大调整:Plus 型号被取消,取而代之的是全新的 iPhone Air(6.5 英寸)。基础版 iPhone 17 与 Pro 版共享同一块 6.3 英寸显示屏,这也意味着基础款首次获得 ProMotion 与 Always-On Display 等 Pro 级特性。值得注意的是,所有新机型在横屏模式下新增了 20 pt 的顶部安全区内边距。
Keith Harrison 整理了所有 iPhone(及 iPod touch)自 iOS 15 起的完整屏幕尺寸与安全区(Safe Area Insets),并更新了 App Store 截图要求:开发者可继续使用 6.9 英寸(1320 × 2868)或 6.5 英寸(1242 × 2688)规格上传主截图。
超越 QA:移动测试策略 (Beyond QA: Mobile Testing Strategies)
移动应用无法"热修复",一旦上线崩溃,就要经历审核与分阶段发布,因此预防远比补救重要。Tjeerd in 't Veen 通过"组合爆炸"问题深入分析了为何仅依赖手动测试远远不够,并探讨了如何构建更全面的移动测试体系。
文章对多种测试策略进行了权衡:手动测试擅长发现 UI 与交互问题,但难以扩展;UI 测试可并行运行大规模流程,但维护成本高;快照测试能捕获视觉回归,却需维护参考图像库。作者建议采用混合策略------以单元测试和 UI 测试覆盖 90% 的功能,用手动测试验证真实网络环境和视觉细节,并将 UI 测试设为可选或定期运行,以避免阻塞开发流程。
用 Swift Subprocess 实现自动化 (Automate All the Things with Swift Subprocess)
在本文中,Jacob Bartlett 用多个示例探讨了如何借助 swift-subprocess------一个旨在以 Swift 的现代特性取代老旧 Process(NSTask)API、简化进程管理的新库------改善 Swift 的脚本化编程体验。对于简单脚本而言,swift-subprocess 仍显笨重:必须创建完整的 SPM 项目,首次运行的依赖解析与编译开销让人怀疑这是否还称得上"脚本"。但在更复杂的自动化工作流(如 CI/CD 流程)中,Swift 的类型安全、模块化与可维护性则展现出优势,虽不如 Bash 精简,却更利于组织与复用。
Jacob 指出,在 LLM 辅助编程时代,Bash 脚本的边际成本几乎为零,且模型对 Bash 的掌握远超 Swift。是否采用 swift-subprocess,应基于实际需求,而非追求"用 Swift 统一所有工具链"的理想。
Swift 并发:那些早该知道的事 (Swift Concurrency: What I Wish Someone Had Told Me)
在过去的六个月中,Bruno Valente Pimentel 完成了三个应用的 Swift 6 并发迁移,他在本文中分享了那些文档里不会提及的"血泪教训"。Bruno 揭示了几个关键陷阱:@MainActor
只保护同步访问,await
之后的世界充满未知;Actor 重入性会引发隐蔽的竞态,需以"任务去重"的方式规避;而过度追求代码洁癖(强制 Sendable
)会拖慢进度,可先用 @unchecked Sendable
、@preconcurrency
解锁开发,再逐步还债。
作者的感悟是:目标不是完美,而是创造比昨天更好的可用软件。
SwiftUI TextEditor 富文本编辑 (Using Rich Text in the TextEditor with SwiftUI)
在 WWDC 2025 中,苹果为 TextEditor 带来了期待已久的富文本支持,让开发者可以直接使用 AttributedString 在 SwiftUI 中编写和编辑样式化文本。Alfonso Tarallo 在文中演示了从基础到编辑交互(选区、属性变换)的完整流程,并特别指出 transformAttributes(in:) 的设计巧妙:它以 inout 方式处理选区,自动合并相邻属性片段,从而避免文本碎片化。
TextEditor 的富文本能力高度依赖于 Foundation 层面对 AttributedString 的重大增强。正如 WWDC Session 中 Jeremy 所强调的,AttributedString 的索引是"一条穿过树的路径",这种设计虽强大,却也更复杂。要真正用好这一特性,开发者不仅需要学习新 API,更要理解一种全新的文本处理范式。
在 Swift Concurrency 中处理单例 (Singletons with Swift Concurrency)
单例作为"全局可变状态",在 Swift Concurrency 的严格模型下成了棘手难题。Matt Massicotte 提供了一份务实的迁移指南,其核心理念是------"向编译器如实表达并发事实"(expressing truth)。
文章系统分析了多种处理方式:如果类型已具备线程安全机制,可使用 @unchecked Sendable
如实声明;若主要在主线程访问,@MainActor
是最诚实且高效的选择。而将类直接改为 actor 或使用自定义全局 actor 虽然能彻底隔离状态,却往往导致过度工程化。Matt 建议开发者与其掩盖现有并发访问模式,不如明确告诉编译器实际情况,让隐形风险显性化。
几天前的一个 Reddit 讨论 引发了热烈争论,Matt 也参与其中。这篇文章是他对该话题的系统性回应,将"如实表达"的原则贯穿始终。
工具
AsyncCombine
虽然 Apple 明确将 Swift Concurrency 作为未来方向,但许多开发者在从 Combine 迁移后都感受到代码可读性的下降------原本简洁的响应式管道,变成了冗长的 for await
循环与手动任务管理。为此, William Lumley 开发了 AsyncCombine,一个基于 AsyncSequence 和 Swift Observation 框架的轻量库。它在保留 async/await 原生特性的同时,重新带回了 Combine 风格的操作符,使开发者能够继续使用熟悉的 sink
、assign
、store(in:)
等 API,编写出更直观、可组合的异步代码。
在处理复杂的异步数据流时,我依然偏爱 Combine 的管道式表达------它让数据变换的意图一目了然。正如 William 在 AsyncCombine: Because Async Code Shouldn't Be Ugly 中所说:强大的功能与优雅的代码并非互斥。
往期内容
THANK YOU
如果你觉得这份周报或者我的文章对你有所帮助,欢迎 点赞 并将其 转发 给更多的朋友。
在 weekly.fatbobman.com 订阅本周报的电子邮件版本。访问我的博客 肘子的 Swift 记事本 查看更多的文章。加入 Discord 社区,与 2000+ 中文开发者深入交流 Swift、SwiftUI 开发体验。