
A Trip to the Apple Store for Repairs
My father’s iPhone 16 suddenly stopped charging. After making an appointment, I took it to the Apple Store for repair. Once the staff confirmed the issue, they provided me with an iPhone 14 as a loaner and helped transfer the data. Twelve days later (which included a long holiday), the device was ready—the Type-C port had been replaced, along with a complimentary new battery. The experience was, as always, satisfying.
Over the years, I’ve had quite a few Apple devices repaired. Some memorable instances include: a free logic board replacement for my MacBook Pro due to the “GPU gate” issue, and a free display replacement for my 2011 27-inch iMac because of dust accumulation behind the screen. For other minor issues, if the timing was right, sometimes they’d simply replace the device entirely.
There’s no shortage of complaints online about Apple Store or authorized service providers. But personally, my repair experiences have been consistently smooth—perhaps thanks to being well-informed about the device issues and maintaining a friendly attitude throughout.
An interesting observation: there are quite a few elderly customers at the Apple Store. Chatting with Genius Bar staff, I learned that many young people pass down their old iPhones or iPads to their elders, or buy new devices as gifts, but often don’t have time to teach them how to use them. As a result, a significant portion of the Genius Bar’s workload has become helping seniors set up accounts, install apps, and learn basic operations.
The Genius Bar’s presence enables users of all ages to enjoy the convenience of technology—serving customers while strengthening brand loyalty. Today, many other brands have opened substantial retail stores, but most remain focused on display and sales. In an era where online shopping has become the norm, the value of physical stores has long transcended “selling products”—it lies in the warmth of face-to-face human interaction. This is precisely the essential appeal of the Apple Store.
Previous Issue|Newsletter Archive
If you appreciate my work and want to promote your product to the Swift and iOS developer community, sponsoring my blog & newsletter could be an excellent opportunity for you.
Recent Recommendations
Hot Reloading SwiftUI Apps
While Xcode Preview offers great convenience for developers to instantly see UI changes, it still has many limitations. Daniel Hooper demonstrates an ingenious hot reloading solution in this article: compile the UI and app logic into a dynamic library that the host app loads at runtime. When code changes, reload the new library and replace the old one. The highlights of this approach include: support for full app execution, state preservation, and independence from Xcode. The entire implementation requires only about 120 lines of code, perfectly embodying the principle that “once you understand the fundamentals, complex features can be implemented elegantly.”
Mastering UITableViewDiffableDataSource
While SwiftUI’s list capabilities continue to improve, UITableView remains irreplaceable for scenarios involving large datasets, complex interactions, or fine-grained control. Compared to SwiftUI’s declarative simplicity, UITableView’s data source management is more error-prone, with batch updates often crashing due to data-UI inconsistencies. Kingnight (Jinkai) systematically explains the modern usage of UITableViewDiffableDataSource through a fully-featured music playlist example.
The article not only covers the basics but also deeply compares the performance trade-offs between reconfigureItems
and reloadItems
, dissects the implementation of drag-to-reorder and swipe-to-delete, and provides reusable architectural practices through BaseReorderableDiffableDataSource and DiffableTableAdapter. Whether integrating UIKit lists in SwiftUI projects or maintaining existing UIKit projects, this is a solid modernization guide.
iPhone 17 Screen Sizes
The iPhone 17 series brings major screen configuration changes: the Plus model is discontinued, replaced by the new iPhone Air (6.5 inches). The base iPhone 17 and Pro versions share the same 6.3-inch display, meaning the base model gets Pro-level features like ProMotion and Always-On Display for the first time. Notably, all new models add a 20pt top safe area inset in landscape mode.
Keith Harrison has compiled complete screen sizes and Safe Area Insets for all iPhones (and iPod touch) since iOS 15, and updated App Store screenshot requirements: developers can continue uploading main screenshots at 6.9” (1320×2868) or 6.5” (1242×2688) specifications.
Beyond QA: Mobile Testing Strategies
Mobile apps can’t be “hot-fixed”—once a crash goes live, you must go through review and staged rollout, making prevention far more important than remediation. Tjeerd in ‘t Veen uses the “combinatorial explosion” problem to analyze why manual testing alone is insufficient and explores how to build a more comprehensive mobile testing system.
The article weighs various testing strategies: manual testing excels at finding UI and interaction issues but doesn’t scale; UI tests can run large-scale flows in parallel but have high maintenance costs; snapshot tests capture visual regressions but require maintaining reference image libraries. The author recommends a hybrid strategy—covering 90% of functionality with unit and UI tests, using manual testing to verify real network environments and visual details, and making UI tests optional or scheduled to avoid blocking development workflows.
Automate All the Things with Swift Subprocess
Jacob Bartlett explores through multiple examples how swift-subprocess—a new library aimed at replacing the aging Process (NSTask) API with Swift’s modern features—can improve Swift scripting experience. For simple scripts, swift-subprocess remains cumbersome: requiring a full SPM project setup, with dependency resolution and compilation overhead on first run that makes one question whether this still counts as “scripting.” However, in more complex automation workflows (like CI/CD pipelines), Swift’s type safety, modularity, and maintainability shine through—less concise than Bash but better for organization and reuse.
Jacob notes that in the age of LLM-assisted programming, the marginal cost of Bash scripts is nearly zero, and LLMs’ mastery of Bash far exceeds Swift. Whether to adopt swift-subprocess should be based on actual needs rather than the ideal of “unifying all toolchains with Swift.”
Swift Concurrency: What I Wish Someone Had Told Me
Over the past six months, Bruno Valente Pimentel completed Swift 6 concurrency migration for three apps, sharing the hard-learned lessons that documentation won’t tell you. Bruno reveals several key pitfalls: @MainActor
only protects synchronous access, the world after await
is full of unknowns; Actor reentrancy can cause hidden race conditions requiring “task deduplication” to avoid; and obsessing over code cleanliness (forcing Sendable
) slows progress—better to use @unchecked Sendable
and @preconcurrency
to unblock development, then pay down technical debt gradually.
The author’s insight: the goal isn’t perfection, but creating software that’s better than yesterday.
Using Rich Text in the TextEditor with SwiftUI
At WWDC 2025, Apple brought long-awaited rich text support to TextEditor, allowing developers to write and edit styled text directly using AttributedString in SwiftUI. Alfonso Tarallo demonstrates the complete workflow from basics to editing interactions (selection, attribute transformations), particularly noting the clever design of transformAttributes(in:): it handles selection as inout, automatically merging adjacent attribute fragments to avoid text fragmentation.
TextEditor’s rich text capabilities heavily depend on major enhancements to AttributedString at the Foundation level. As Jeremy emphasized in the WWDC Session, AttributedString indices are “paths through a tree”—a design that’s powerful yet complex. To truly master this feature, developers need not just to learn new APIs, but to understand an entirely new text processing paradigm.
Singletons with Swift Concurrency
Singletons, as “global mutable state,” have become a thorny issue under Swift Concurrency’s strict model. Matt Massicotte provides a pragmatic migration guide centered on the core principle of “expressing truth” to the compiler about concurrency facts.
The article systematically analyzes various approaches: if a type already has thread-safety mechanisms, use @unchecked Sendable
to honestly declare it; if accessed mainly on the main thread, @MainActor
is the most honest and efficient choice. While converting classes directly to actors or using custom global actors can completely isolate state, it often leads to over-engineering. Matt advises developers to explicitly tell the compiler what’s actually happening rather than hiding existing concurrency patterns, making invisible risks visible.
A Reddit discussion from a few days ago sparked heated debate, with Matt participating. This article is his systematic response to that topic, with the principle of “expressing truth” running throughout.
Tools
AsyncCombine
While Apple has clearly positioned Swift Concurrency as the future direction, many developers have experienced a decline in code readability after migrating from Combine—what were once clean reactive pipelines have become verbose for await
loops and manual task management. To address this, William Lumley developed AsyncCombine, a lightweight library built on AsyncSequence and the Swift Observation framework. It preserves native async/await features while bringing back Combine-style operators, allowing developers to continue using familiar APIs like sink
, assign
, and store(in:)
to write more intuitive, composable asynchronous code.
When dealing with complex asynchronous data flows, I still prefer Combine’s pipeline-style expression—it makes the intent of data transformations immediately clear. As William puts it in AsyncCombine: Because Async Code Shouldn’t Be Ugly: powerful functionality and elegant code are not mutually exclusive.
去 Apple Store 修手机
父亲的 iPhone 16 突然无法充电。预约后,我前往 Apple Store 送修。工作人员确认问题后,为我提供了一部 iPhone 14 作为备用机,并协助完成数据转移。十二天后(期间正好赶上一个长假),设备维修完成——更换了 Type-C 接口,同时还免费更换了一块新电池。体验一如既往地令人满意。
这些年来,我修过不少苹果设备。印象较深的几次包括:因“显卡门”事件,MacBook Pro 免费更换主板;2011 款 iMac 27 英寸因屏幕进灰,免费更换显示屏。其他一些小问题,如果时机合适,有时会直接换新设备。
网络上确实不乏关于 Apple Store 或授权维修商的不愉快经历。但就我个人而言,多次维修体验都算顺利——或许得益于对设备问题的充分了解,以及始终保持友好的沟通态度。
一个有趣的观察是:Apple Store 里有相当多的老年用户。与天才吧工作人员闲聊时得知,许多年轻人会把淘汰的 iPhone 或 iPad 送给长辈,或直接购买新设备作为礼物,但往往没有时间教他们使用。于是,天才吧相当一部分工作量,变成了帮助老年人注册账户、安装应用、指导基本操作。
天才吧的存在,让全年龄段用户都能享受科技的便利——既服务了消费者,也增强了品牌的用户粘性。如今许多其他品牌也开设了规模不小的线下门店,但大多仍停留在展示与销售层面。在网购已成主流的时代,实体店的价值早已超越“卖产品”,更在于那种人与人面对面交流的温度——这,正是 Apple Store 的重要魅力所在。
如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 爱发电,Buy Me a Coffee 支持我的创作。
近期推荐
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 中所说:强大的功能与优雅的代码并非互斥。
Yup. That’s why I buy fruit devices for Mom. I don’t have to be tech support. 🤓 (And they have features the competition doesn’t. Her Apple Watch called for emergency services when the hard fall detection triggered.)