Fatbobman's Swift Weekly #147
Hot Tea or Iced Coffee

Hot Tea or Iced Coffee
Recently, the temperatures in my city have been breaking historical records. Since the end of July, we’ve been stuck in a stretch of scorching weather lasting more than ten days, with temperatures consistently above 30°C. While that may not sound particularly extreme on its own, paired with humidity exceeding 80%, it leaves behind a lingering sense of heat that never quite goes away—even after spending the entire day in an air-conditioned room set to 25°C.
I’ve found myself turning to tea and coffee to improve how I feel. Interestingly, only a cup of hot tea gives me the satisfying sensation of heat escaping with perspiration, while only an iced coffee brings an immediate, refreshing coolness. I suspect this isn’t simply a matter of physics. More likely, it’s a psychological association shaped by years of habit.
There’s an old Chinese saying: “A calm mind brings a cool body.” I can’t claim to have reached that level of serenity. For now, I still rely on these simple drinks to help me find a bit of balance between warmth and coolness.
Hopefully, this hot and humid summer will return to normal sooner rather than later.
Previous Issue|Newsletter Archive
📢 Sponsor Fatbobman’s Swift Weekly
Promote your product to Swift & iOS developers across:
- Blog: 50,000+ monthly visitors
- Newsletter: 4,000+ subscribers, 53% open rate
Perfect for developer tools, courses, and services.
Enjoyed this issue? Buy me a coffee ☕️
Recent Recommendations
Liquid Glass: A Field Guide to UIKit Compatibility Pitfalls
While Liquid Glass introduces a fresh interaction experience, it also makes UIKit compatibility significantly more complex. The same UI can behave very differently across iOS 18, iOS 26, and iOS 27, while different API combinations and implementation approaches may introduce their own compatibility pitfalls. Drawing from real-world project experience, Megabits summarizes common issues involving Sheets, Navigation, Popovers, Toolbars, and other UIKit components, while also explaining lower-level behaviors such as UIBarButtonItem, CABackdropLayer, and the Scroll Edge Effect, complete with practical solutions and runnable demos.
The Map, Drawn Twice
Apple’s UI rendering stack spans Core Graphics, Core Text, Core Image, Core Animation, and SwiftUI. Although developers work with these frameworks regularly, many never fully understand the distinct responsibility of each layer. In the inaugural issue of Apple UI Insider, Mihaela Mihaljević Jakić presents a conceptual map that traces the journey from Swift code to the final pixels on screen.
Mihaela adopts a fascinating validation approach: every illustration is rendered twice from the exact same scene description—once by a custom clean-room rendering engine, and once by Apple’s Core Graphics—before being compared pixel by pixel. Although nearly half of the pixels differ, the average pixel difference is only around 0.1%, making the two images visually almost indistinguishable. This methodology of understanding system behavior through independent implementations, reproducible experiments, and quantitative measurements is arguably even more compelling than the article itself, and makes the rest of the series especially worth looking forward to.
Finally found a use case for .fixedSize
.fixedSize is one of SwiftUI’s most overlooked modifiers. Many developers associate it only with niche use cases such as preventing text wrapping. Starting from a common layout requirement—making every card inside a horizontal ScrollView match the height of the tallest one—Omar Elsayed demonstrates how .fixedSize provides an elegant solution.
Perhaps
.fixedSizehas never become widely adopted because its name is rather abstract. What exactly is being “fixed”? And what does “size” actually refer to? If you’d like to better understand why it changes layout behavior, you may find my previous series, SwiftUI Layout: The Mystery of Size, helpful. It recreatesfixedSizefrom scratch and breaks down the layout negotiation mechanism behind it.
Two Interesting Explorations of LazyVStack’s Layout Mechanism
On the Apple Developer Forums, alextar04 published two in-depth analyses of LazyVStack. One investigates blank screens and truncated cells during fast scrolling, while the other examines why GeometryReader reports multiple different sizes when used inside a LazyVStack (Thread 2). Beyond providing minimal reproducible examples, the author combines insights from the WWDC 26 Lazy Stack session, SwiftUI logging, and experimental observations to reconstruct how SwiftUICore—including symbol resolution and CA::Transaction validation—might estimate sizes and validate layouts, using these hypotheses to explain the observed behavior.
These two posts also highlight the design differences between
ListandLazyVStackfrom another perspective. The author suggests that, in order to support lazy layout,LazyVStackrelies on size estimation under certain circumstances, which naturally leads to behavior different fromList. This further illustrates why neither container is universally better—their strengths simply apply to different scenarios.
Swift on Windows: A Year of Refinement
A year ago, Swift on Windows had already proven itself capable of supporting real production applications. But being “functional” is not the same as being predictable. Over the past year, The Browser Company, together with Apple and the Swift community, has focused on strengthening the platform’s foundations: rebuilding the runtime build system with modern CMake, introducing the Experimental Swift SDK, formalizing both static and dynamic linking models, and improving runtime selection and distribution across multi-toolchain environments.
What truly advances the maturity of a cross-platform ecosystem is often not a headline-grabbing feature, but the engineering details that are easy to overlook: whether build configurations are reproducible and auditable, whether runtimes can be bound deterministically, whether tools can be distributed independently, and whether CI and developer environments behave consistently. This article offers an excellent overview of how Swift on Windows has evolved over the past year—not through flashy new capabilities, but through continuous refinement of its engineering foundations.
Memo Property: Reusing More Stateful Business Logic for SwiftUI Views
In TaskProperty, Rick Van Voorden demonstrated how custom DynamicProperty types can extract stateful business logic from SwiftUI views while remaining aligned with the view lifecycle. Building on that idea, this article leverages Swift’s latest Parameter Packs (Variadic Generics) to implement a React-like useMemo mechanism for SwiftUI: filtering, sorting, and other expensive computations are recomputed only when explicitly declared dependencies change, while cached results are reused for unrelated view updates.
One Model Object, Multiple Editing Flows: The Missing Layer Between Model and UI
Since the introduction of Observation, many developers have assumed that Combine is gradually becoming less relevant in SwiftUI. In this article, Sergey Tristan presents a different perspective. When multiple independent editing flows share the same model object, with each flow interested in only part of its state, Observation excels at efficiently detecting changes, while Combine is better suited for composing, transforming, and continuously synchronizing data. Rather than replacing one another, the two complement each other.
The article introduces a Projection layer between the model and the UI that transforms one or more continuously changing data sources into reactive representations tailored for different consumers. Whether or not you adopt this architecture, it raises an interesting question: as applications evolve to include increasingly independent yet interconnected editing flows, do we need an abstraction beyond DTOs, ViewModels, and Observation to organize these continuously evolving data flows?
Tools
Apple External Display Support Lookup
External display support across Apple devices can be surprisingly complicated. Capabilities vary by chip generation, hardware model, and even operating system version. Created by Parish Khan, RetinaDesk provides a convenient online lookup tool that lets you quickly check how many external displays a Mac, iPad, or iPhone supports, along with maximum resolution, refresh rate, extended display support, mirroring capabilities, and more.
For developers working with multi-display setups, Stage Manager, or external display features, this is a handy reference that makes it much easier to verify device capabilities without digging through Apple’s technical specifications.
Agent Island
Agent Island is an open-source local monitoring tool created by Tristan Tang. It continuously monitors the local session files generated by Claude Code and Codex, determines their current state in real time, and displays intuitive status updates and notifications through a Dynamic Island-style menu bar interface, so you no longer need to keep watching your terminal. It can also automatically execute predefined follow-up actions once your AI model usage window resets, helping long-running tasks resume seamlessly.
The project follows a local-first design, requiring no cloud services and uploading no conversation data. It also provides token usage statistics, quota reset countdowns, and weekly/monthly usage reports.
Thanks for reading Fatbobman’s Swift Weekly! This post is public so feel free to share it.
热茶还是冰咖啡
最近我所在的城市,气温不断刷新历史纪录。从 7 月末开始,便陷入了持续十天以上、超过 30 摄氏度的高温酷暑。尽管从绝对数值上看并不算惊人,但配上超过 80% 的湿度,即便全天待在 25 度的空调房里,体内依然能攒出一股挥之不去的燥热。
我会通过喝茶、喝咖啡来改善“体感”。有意思的是,唯有热茶能带给我一种热量随汗水释放的通透感,而也唯有冰咖啡能带来片刻直截了当的清凉。我想,这未必是饮品本身的物理特性使然,或许更多是长期饮食习惯在心中留下的心理暗示。
中国有句老话叫“心静自然凉”。我自认还没达到这般超脱的心境,现阶段仍免不了借助这些杯中物,在冷热之间寻得一点平衡。
但愿这个闷热的夏天,能早点复归常态。
如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 Buy Me a Coffee 支持我的创作。
近期推荐
Liquid Glass:UIKit 适配踩坑实录
Liquid Glass 在带来全新交互体验的同时,也让 UIKit 的兼容性变得更加复杂。同一套 UI,在 iOS 18、iOS 26 与 iOS 27 上可能表现出截然不同的行为;不同的 API 组合与实现方式,也可能触发各式各样的兼容性问题。Megabits 结合真实项目经验,总结了 UIKit 下 Sheet、Navigation、Popover、Toolbar 等多个典型场景中的适配陷阱,并分析了 UIBarButtonItem、CABackdropLayer、Scroll Edge Effect 等底层行为,给出了对应的解决方案与可运行 Demo。
两度绘制的像素渲染地图 (The Map, Drawn Twice)
Apple 的 UI 渲染体系涉及 Core Graphics、Core Text、Core Image、Core Animation 与 SwiftUI 等多个层次,开发者虽然经常使用这些框架,却未必真正理解它们各自承担的职责。在 Apple UI Insider 的创刊号中,Mihaela Mihaljević Jakić 绘制了一张从 Swift 代码到最终像素的职责地图。
Mihaela 采用了一种很有意思的验证方式:每一张插图都由同一份场景描述生成两次,一次交给自己实现的 clean-room 渲染引擎,另一次交给 Apple 的 Core Graphics,再逐像素比较两者的输出。尽管约有一半像素存在差异,但平均像素差异仅约为 0.1%,视觉效果几乎完全一致。这种通过独立实现、可复现实验和量化结果来研究系统行为的方法,比文章本身介绍的内容更值得关注,也让人更加期待这一系列后续的研究。
终于为 .fixedSize 找到了合适场景 (Finally found a use case for .fixedSize)
.fixedSize 是 SwiftUI 中一个经常被忽视的 modifier,不少开发者对它的印象仍停留在避免文本折行等少数场景。Omar Elsayed 从一个很常见的需求出发:如何让横向 ScrollView 中所有卡片都与最高的那一项保持相同高度,分享了自己借助 .fixedSize 找到解决方案的过程。
或许
.fixedSize一直没有得到广泛使用,与它略显抽象的命名也有一定关系。究竟固定的是什么?对应的 size 又是什么?如果想深入理解它为何能够改变布局结果,可以参阅我之前写的《SwiftUI 布局:尺寸》系列,其中通过实现fixedSize的复制品,拆解了它在 SwiftUI 布局协商中的工作机制。
关于 LazyVStack 布局机制的两次有趣探索
在 Apple Developer Forums 上,alextar04 连续发布了两篇关于 LazyVStack 的分析帖。两篇帖子分别围绕快速滚动时可能出现的空白区域与 Cell 截断,以及 GeometryReader 在 LazyVStack 中获取到的尺寸为何会多次变化展开(帖子 2)。作者不仅提供了最小复现工程,还结合 WWDC 26 关于 Lazy Stack 的介绍、SwiftUI 日志以及实验结果,尝试还原 SwiftUICore 底层(如符号计算与 CA::Transaction 提交验证)在估算尺寸、校验布局时可能采用的工作方式,并据此解释这些现象产生的原因。
这两篇帖子也从另一个角度展现了
List与LazyVStack在设计理念上的差异。作者推测,LazyVStack为了实现懒布局,会在部分场景下依赖尺寸估算等机制,因此与List呈现出不同的行为。这也说明了为什么两者并不存在绝对的优劣,而是各自适用于不同的场景。
Swift on Windows:一年的打磨与完善 (Swift on Windows: A year of refinement)
Swift on Windows 在一年前已经能够支撑真实的生产应用,但“可以运行”并不等于“足够可预测”。The Browser Company 与 Apple 及 Swift 社区将重点放在了基础设施的打磨上:使用现代 CMake 重构 Runtime 构建系统,推出 Experimental Swift SDK,明确静态与动态链接模型,并改善多工具链环境中的 Runtime 选择与分发问题。
真正推动跨平台成熟度提升的,往往不是某个引人注目的新特性,而是这些容易被忽视的工程细节:构建配置是否可审计、Runtime 能否精确绑定、工具是否可以独立分发,以及 CI 与开发环境能否始终保持一致。这篇文章很好地展示了 Swift 在 Windows 平台过去一年最重要的进步,更多来自工程能力的持续打磨,而非功能上的扩张。
MemoProperty:在 SwiftUI 中复用有状态业务逻辑 (Memo Property: Reusing More Stateful Business Logic for SwiftUI Views)
在 TaskProperty 中,Rick Van Voorden 展示了如何借助自定义 DynamicProperty,将带有生命周期和状态的业务逻辑从 View 中抽离出来。本文沿着相同的思路继续向前,结合 Swift 最新的参数包(Parameter Packs / Variadic Generics)等前沿语法,尝试在 SwiftUI 中实现一个类似 React useMemo 的机制:只有当显式声明的依赖发生变化时,才重新执行过滤、排序等计算,否则直接复用此前缓存的结果,避免 View 因无关状态变化而重复完成昂贵工作。
多流编辑下的状态同步:构建模型与 UI 之间缺失的“投影层” (One Model Object, Multiple Editing Flows: The Missing Layer Between Model and UI)
Observation 出现之后,不少开发者开始认为 Combine 在 SwiftUI 中已经逐渐失去价值。Sergey Tristan 的这篇文章则提供了一个不同的视角:当同一个模型对象需要被多个独立的编辑流程共享,并且每个流程只关心其中一部分状态时,Observation 负责高效地感知变化,而 Combine 更适合承担数据组合、转换与持续同步的职责,两者并非替代关系,而是可以各司其职。
文章提出了一个位于 Model 与 UI 之间的 Projection 概念,将一个或多个持续变化的数据源转换为不同消费者所需的响应式表示。无论是否认同这种架构,它都提出了一个值得思考的问题:当应用开始拥有越来越多独立却又相互关联的编辑流程时,是否需要一种不同于 DTO、ViewModel 或 Observation 的抽象来组织这些持续演化的数据流?
工具
Apple 外接显示器支持查询
苹果设备对外接显示器的支持一直比较复杂,不同芯片、不同机型,甚至不同系统版本之间都存在明显差异。由 Parish Khan 创建的 RetinaDesk 提供了一个在线查询工具,可以快速了解 Mac、iPad、iPhone 等设备支持的外接显示器数量、最高分辨率、刷新率,以及是否支持扩展显示、镜像模式等信息。
对于需要测试多屏显示、Stage Manager 或外接显示器相关功能的开发者,这也是一个很方便的参考工具,能够快速确认不同设备组合的能力边界,而无需逐一查阅 Apple 官方技术规格。
Agent Island
Agent Island 是一个由 Tristan Tang 开发的开源本地状态监视工具,它会持续读取 Claude Code 与 Codex 在本地生成的会话记录,实时判断当前状态,并通过菜单栏中的“灵动岛”样式组件提供直观的状态显示与提醒,让开发者无需一直盯着终端。它还支持在 AI 模型额度窗口重置后自动执行预设的后续操作,帮助长时间运行的任务更顺畅地衔接下去。
项目采用 Local-first 设计,不依赖云端服务,不上传任何会话内容,同时提供 Token 使用统计、额度重置倒计时、周/月报告等功能。

