Fatbobman's Swift Weekly #146
It's Not That the Models Are Slower—The Tasks Have Become Bigger

It’s Not That the Models Are Slower—The Tasks Have Become Bigger
Lately, even tasks that I consider relatively simple often take AI several minutes—or sometimes even tens of minutes—to complete. It gave me the impression that as models become more capable, they somehow have to become slower.
In reality, the main reason lies with me. Although today’s AI agents let us choose different models and reasoning levels, it’s much easier—and often more reliable—to simply hand even straightforward tasks to the most capable models. At the same time, modern agents no longer limit themselves to the small change you explicitly requested. They proactively expand their search, analyze whether the modification could affect other parts of the project, and try to identify potential issues before they happen. The models may be more powerful than ever, but they’re also taking on substantially more work for every task.
There’s another factor as well. As my trust in these models has grown, so has the scope of the tasks I assign to them. What used to be “refactor a function” or “improve a screen” has gradually become “implement a feature,” “build a module,” or even “create an entire product.” Without realizing it, I’ve started treating AI agents as genuine collaborators. The pace at which model performance improves simply hasn’t kept up with the way we now use them.
In other words, developers are no longer pursuing only “writing code faster.” Increasingly, we’re using AI to write better code, even if it takes longer.
The shift from question-answering to task delivery has happened in just a single year. As we grow accustomed to waking up and reviewing completed work, the real bottleneck is quietly moving elsewhere. We used to ask whether a model was capable of completing a task. Today, the more important questions are how to define a clear, verifiable objective, and how to reduce the cost of achieving it. AI is becoming more like a teammate, and the ability to organize and decompose work effectively is becoming the next competitive advantage.
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
Bluetooth without the delegate dance
Delegates remain a challenge many developers continue to face years after the introduction of Swift Concurrency. Not only do they often lead to cumbersome code organization, but under Swift 6’s strict concurrency checking they also become increasingly difficult to integrate naturally with modern concurrent code. Kyle Browning leverages Swift 6.2’s Custom Executor to bind CoreBluetooth’s callback queue directly to an Actor’s execution context, allowing delegate callbacks to run naturally within Actor isolation without additional locks, thread hopping, or synchronization logic.
Custom Executor allows an Actor’s tasks to run on a designated executor, making it a powerful tool for bridging traditional callback-based APIs with Swift Concurrency. If you’re facing similar migration or abstraction challenges, this implementation is well worth studying. I also explored this topic in depth using Core Data as an example in this article, explaining how to bind traditional serial queues to Actor executors for seamless integration with Swift Concurrency.
Working with Xcode on CI
As more developers adopt self-hosted macOS runners or cloud-based CI, reliably managing Xcode, Simulator Runtimes, and code-signing environments has become an essential part of engineering infrastructure. Dmitry Rodionov shares a collection of practical techniques for using the Xcode CLI in CI, including managing multiple Xcode installations with DEVELOPER_DIR instead of xcode-select, automating the installation and cleanup of Simulator Runtimes and Metal Toolchains, and reducing unnecessary recompilation during branch switching with Compilation Caching.
Squeeze every last bit of value out of GitHub Actions
Optimizing GitHub Actions doesn’t necessarily mean more aggressive caching, more complex workflows, or additional conditional logic. Instead, this article advocates a more valuable principle: every CI run should match the actual risk introduced by a change. Starting from the investigation of an apparently ordinary flaky test, Snow discusses how deterministic tests eliminate unnecessary reruns, how portable checks can be moved to Linux while leaving Xcode-dependent validation to macOS, and how Build, Test, or Build for Testing can be selected dynamically based on change risk to avoid wasting expensive runner time.
I particularly agree with one of the article’s core ideas: the goal of CI is not to “run more,” but to “answer the right questions.” Every expensive macOS build should validate a risk that a cheaper runner cannot, and every failure should provide actionable information that helps move the project forward.
Building adaptive non-modal panels in SwiftUI
Starting with WWDC26, iPhone-only apps running through iPhone Mirroring on a Mac or on an iPad enter a resizable environment. This means relying solely on horizontalSizeClass for layout decisions is becoming increasingly unreliable. Matthaus Woolard demonstrates how to build an adaptive non-modal panel by recording scene size and safe-area insets at the root using onGeometryChange, then choosing between bottom and side presentations based on the actual available width. One particularly useful technique is preserving the resolved layout cache during dragging, preventing adaptive content from changing size due to repeated measurements.
If your app is iPhone-only but still has users running it on iPad or macOS, layout adaptation deserves much more attention going forward. As discussed in From Size Class to Available Space, the era of resizable canvases no longer guarantees developers absolute control over interface layouts, instead giving users much greater control over how apps are presented.
SwiftUI @ContentBuilder - Faster Type Checking in Xcode 27
Xcode 27 introduces the new @ContentBuilder. Although it is currently just a type alias for ViewBuilder, Apple has begun recommending this new name in its latest SwiftUI APIs. Sagar Unagar explains the change and notes that, for most applications, there is no need to immediately replace every @ViewBuilder with @ContentBuilder, as existing code already benefits from the compiler improvements introduced in Xcode 27.
I haven’t written much SwiftUI code recently, so I haven’t yet experienced firsthand whether this change significantly improves compilation performance. That said, in previous projects I often noticed Xcode struggling with type inference and code completion whenever different builder content was mixed inside a
ViewBuilder, especially with APIs like Table and Charts. If Xcode 27 truly improves these scenarios, then this change represents much more than just a new builder name.
Tool
tswift: A Lightweight Swift Runtime Built with Rust
Without relying on the Swift toolchain, LLVM, code generation, or any C dependencies, tswift can parse, semantically analyze, and execute Swift source code. Developed by Francis Chong, tswift implements the Swift frontend entirely in Rust, handling lexical, syntactic, and semantic analysis before interpreting Swift language semantics and standard library behavior through a tree-walking runtime.
Beyond the language runtime itself, the project is also exploring framework support. SwiftUI already has a basic rendering pipeline, while Charts currently implements 58 of 60 range-related members, can render Web SVG output, and can bridge to Apple’s native Charts framework on iOS.
Whether it’s the C-based miniSwift, the recent signs of the Swift compiler’s self-hosting progress, or the Rust-based tswift runtime, they all demonstrate that the Swift ecosystem is evolving toward a more open and diverse implementation landscape. As more implementation paths emerge, Swift’s cross-platform potential continues to grow beyond what many expected.
Thanks for reading Fatbobman’s Swift Weekly! This post is public so feel free to share it.
不是模型变慢了,是任务变大了
最近,即便是一些我认为并不算复杂的工作,AI 交付结果也常常需要几分钟,甚至几十分钟。这让我产生了一种错觉:难道随着模型能力不断增强,速度只能越来越慢?
其实,真正的原因更多来自于我自己。虽然 Agent 提供了模型和思考强度的调整选项,但为了省事,也为了追求更高的成功率,我越来越习惯把一些原本并不复杂的任务直接交给高级模型。与此同时,如今的 Agent 也不会像过去那样只关注你要求修改的那一小块代码,而是会主动扩大搜索范围,分析改动是否会影响整个项目,并尝试提前发现潜在问题。模型虽然更强了,但完成一次任务所承担的工作也明显更多了。
除此之外,随着我对模型能力的信任不断提高,交给它的任务粒度也发生了变化。从最初修改一个函数、优化一个页面,到实现一个功能、完成一个模块,甚至直接开发一个产品,我已经不知不觉把 Agent 当成了一位真正的协作者。模型速度的提升,已经跟不上使用方式变化的速度。
换句话说,开发者追求的已经不再只是“更快地写代码”,而是借助 AI“更慢地写出更好的代码”。
从问答式,到交付式,只用了短短一年时间。当我们开始习惯一觉醒来接收成果时,真正的瓶颈也悄然发生了变化。过去,我们关心的是模型能不能完成任务;现在,更重要的问题变成了如何定义一个清晰、可验证的目标,以及如何降低实现目标的成本。模型越来越像团队成员,而高质量地组织和拆解工作,也正在成为新的效率竞争力。
如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 Buy Me a Coffee 支持我的创作。
近期推荐
用现代并发技术开发蓝牙应用 (Bluetooth without the delegate dance)
Delegate 仍是很多开发者在 Swift Concurrency 已经推出数年后不得不面对的问题:不仅代码组织繁琐,在 Swift 6 的严格并发检查下,也越来越难与现代并发代码自然协作。Kyle Browning 利用 Swift 6.2 的 Custom Executor,将 CoreBluetooth 的回调队列与 Actor 的执行上下文绑定,使 Delegate 回调天然运行在 Actor 隔离环境中,无需额外的锁、线程切换或同步逻辑。
Custom Executor 可以让 Actor 中的任务运行在指定的执行器上,是连接传统回调 API 与 Swift Concurrency 的一项重要能力。如果你也面临类似的迁移或封装问题,不妨参考作者的实现思路。我也曾在这篇文章中,以 Core Data 为例,详细介绍了如何利用 Custom Executor 将传统串行队列与 Actor 执行器绑定,实现与 Swift Concurrency 的自然融合。
CI 环境下的 Xcode 管理实践 (Working with Xcode on CI)
随着越来越多开发者采用自建 macOS Runner 或云端 CI,稳定地管理 Xcode、Simulator Runtime 与签名环境,已成为工程维护的重要组成部分。Dmitry Rodionov 围绕 Xcode CLI 在 CI 中的使用,总结了不少个人心得,例如使用 DEVELOPER_DIR 替代 xcode-select 管理多版本 Xcode、自动安装与清理 Simulator Runtime 和 Metal Toolchain,以及利用 Compilation Caching 减少分支切换带来的重复编译。
榨干 GitHub Actions 的最后一点价值
GitHub Actions 的优化,未必意味着更激进的缓存、更复杂的 Workflow,或更多的条件判断。这篇文章提出了一个值得借鉴的思路:让每一次 CI 执行都与实际风险相匹配。Snow 从一次看似普通的 Flaky Test 排查开始,逐步讨论了如何用确定性测试消除无意义的重跑、将可移植的检查迁移到 Linux、仅把真正依赖 Xcode 的验证留给 macOS,以及根据变更风险动态选择 Build、Test 或 Build for Testing,避免昂贵的 Runner 执行不必要的工作。
我很认同文中的一个观点:CI 的目标不是“跑得更多”,而是“回答正确的问题”。每一次昂贵的 macOS 构建,都应该验证一个更便宜的 Runner 无法验证的风险;每一次失败,也都应该提供足以推动修复的信息。
在 SwiftUI 中构建自适应非模态面板 (Building adaptive non-modal panels in SwiftUI)
从 WWDC 26 开始,iPhone-only 应用在通过 iPhone Mirroring 显示到 Mac,或在 iPad 上运行时,将进入可变尺寸环境。这意味着仅依赖 horizontalSizeClass 判断布局形态已经越来越不可靠。Matthaus Woolard 介绍了如何构建一个自适应的非模态 Panel:通过 onGeometryChange 在场景根部记录窗口尺寸与 Safe Area,根据真实可用宽度决定面板显示在底部还是侧边。其中,在拖动期间保留已经解析的布局缓存,避免自适应内容因重复测量而出现尺寸跳变,是一个相当实用的技巧。
如果你的应用是 iPhone-only,并且仍有用户会在 iPad 或 macOS 上使用它,那么从今年开始就需要特别关注布局的适配。可变画布 从某种意义上来说,不再保证开发者对界面布局拥有绝对控制权,而是将更多的选择权交到了用户手中。
SwiftUI @ContentBuilder:大幅提升 Xcode 27 编译效率 (SwiftUI @ContentBuilder - Faster Type Checking in Xcode 27)
Xcode 27 引入了新的 @ContentBuilder。虽然它目前仍只是 ViewBuilder 的类型别名,但 Apple 已开始在新的 SwiftUI API 中推荐使用这一名称。Sagar Unagar 介绍了这一变化,同时指出,对大多数应用来说,并没有必要立即将所有 @ViewBuilder 替换成 @ContentBuilder,已有代码在 Xcode 27 下同样能够受益于编译器的改进。
我最近并没有怎么写 SwiftUI 代码,因此还没有亲身体会到这个改动是否真正带来了编译效率上的提升。不过在之前的开发中,无论是 Table 还是 Charts,当将不同的 Builder 内容混写到
ViewBuilder中时,Xcode 的类型推导和代码补全都会明显变慢。如果 Xcode 27 确实改善了这类场景,那么这次调整的意义就远不止一个新的 Builder 名称。
工具
tswift: 用 Rust 构建轻量 Swift 运行时
无需 Swift 工具链、LLVM、代码生成或 C 依赖,即可解析、语义分析并执行 Swift 源码。Francis Chong 开发的 tswift 以纯 Rust 实现了 Swift 前端,完成词法、语法与语义分析,再通过树遍历运行时实现 Swift 的语言语义与标准库行为。
除语言运行时外,项目也在探索框架层面的支持:SwiftUI 已具备基础渲染能力,Charts 支持覆盖 58/60 个范围成员,可输出 Web SVG,并可下沉到 iOS 原生 Charts。
无论是 C 编写的 miniSwift、Swift 编译器近期展现出的自举迹象,还是以 Rust 构建的 tswift,都展现出 Swift 生态正朝着更加开放、多元的实现方向发展。越来越丰富的实现路径,也让 Swift 的跨平台潜力呈现出超出预期的可能性。

