Fatbobman's Swift Weekly #152

When the Mac mini’s Price Is No Longer Mini

Read on web →

Late last month, Apple released the new Mac mini and Mac Studio. Alongside the impressive performance upgrades, the noticeably higher prices were just as striking. Rising memory and storage costs are undoubtedly a major factor, but in the AI era, developers’ hardware needs are also quietly changing. More memory and more storage keep raising our idea of what counts as a “good enough” configuration—and pushing the price we actually pay even higher.

Over the past few months, one of the biggest annoyances in my development work has been the constant noise of my MacBook Pro’s fans. For years, I would only really notice them under a handful of heavy workloads. But in the age of AI agents, having the fans running has become almost routine. Limited by the space inside a laptop and the size of its fans, the noise under sustained load also tends to be more noticeable—and more irritating—than on a desktop machine like the Mac mini.

At the same time, I’ve realized that the MacBook no longer feels as indispensable to my workflow as it once did. Unless I have a specific need, a phone and a tablet are already enough for quite a few Vibe Coding scenarios on short trips. Even when I do need a laptop, a lighter and less powerful model would probably be more than sufficient. So I’ve started seriously considering moving my primary development environment from a MacBook Pro to a Mac mini or Mac Studio.

That brings up another problem: for a primary development machine, memory capacity is a hard requirement. I have almost no need to run LLMs locally, but if I’m upgrading my computer, the new machine needs to offer meaningfully more than the 64GB I already have for the upgrade to feel worthwhile. That essentially rules out the M5 Pro Mac mini, leaving me with the M5 Max and M5 Ultra Mac Studio.

Interestingly, the next memory tier above 64GB is 128GB on one and 96GB on the other, yet the final prices are remarkably close. One gives me more memory; the other, a more powerful chip. I’m not usually someone who struggles to make a choice, but this one has genuinely left me undecided.

Meanwhile, OpenClaw’s popularity has drawn the attention of many consumers who previously had little interest in the Mac mini. OpenAI has also reportedly purchased tens of thousands of Mac minis and Mac Studios for reinforcement learning and training computer-use agents. AI-driven demand at one point grew far faster than Apple had anticipated. Combined with pressure on memory supply and advanced chip manufacturing capacity, this has kept the Mac mini and Mac Studio in short supply over the past few months. Even with the new generation now available, getting the exact configuration you want quickly is still not necessarily easy.

The productivity gains brought by AI may not yet be fully visible across society, but its appetite for compute, memory, and storage resources is already showing up in the hardware market. From components to complete systems, a wide range of consumer hardware is facing new pricing pressure. The old upgrade cycle—waiting a few years and spending roughly the same amount for a substantially more powerful computer—seems increasingly difficult to sustain, at least for now.

But there’s another side to the story: we can’t blame everything on rising prices. While AI is pushing hardware costs upward, it is also changing how we develop software and quietly raising our definition of what counts as a “good enough computer.” Hardware has become more expensive, but we’ve also started asking more of it.

Hopefully, one day we’ll get back to a time when buying a Mac mini doesn’t require quite so much mental preparation.

Previous IssueNewsletter 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.

📢 View Sponsorship Options

Enjoyed this issue? Buy me a coffee ☕️


Original

SwiftData: Optimization Starts with Modeling

Once the dataset grows large, SwiftData lists start to lag. This is one of the performance complaints I’ve heard most often over the past few years. Developers’ first instinct is usually to blame SwiftUI’s List. It certainly bears some responsibility, but it isn’t the main culprit. A closer look reveals that long loading times aren’t the only thing dragging down performance—massive memory consumption is just as important. In this article, I’ll explore why these problems arise in SwiftData and why optimization should start with data modeling.

Some capabilities that appear to be missing from SwiftData may actually have been left out intentionally, reducing the learning curve by exposing fewer APIs and abstraction layers. Therefore, when optimizing SwiftData applications, it’s also worth letting go of some habits carried over from the Core Data era.

Recent Recommendations

The End of Swift Talk

After ten years and 500 episodes, Chris Eidhof and Florian Kugler have announced the end of Swift Talk. Since its launch in June 2016, Swift Talk has accompanied Swift through nearly its entire journey toward maturity, while also witnessing SwiftUI grow from its introduction into a core UI framework for Apple platform development. Through a long series of deep and highly experimental episodes, the two explored Swift, SwiftUI, layout, animation, concurrency, and many lower-level topics rarely covered in conventional tutorials. They hope to make the complete archive of more than 500 episodes available to the community by the end of this year.

For me, objc.io and Swift Talk have always occupied a very special place in the Swift community. Chris and Florian were rarely satisfied with simply telling developers how an API “should be used.” Instead, they would experiment, refactor, and sometimes even reimplement things to understand why a framework works the way it does. This approach to exploration has influenced many Swift developers, myself included. Thank you, Chris and Florian, for the time, knowledge, and curiosity you’ve contributed to the Swift community over all these years, and for the invaluable archive Swift Talk leaves behind.


What’s new in Swift: August 2026 Edition

Swift has published its August ecosystem update, curated by Simon Leeb and Dave Lester, covering noteworthy community projects, package updates, and Swift Evolution developments. What interests me most is Swift’s progress on the Web: Simon Leeb demonstrated a Full-Stack Swift on Cloudflare Demo, with Swift running in the browser through ElementaryUI and WebAssembly, a backend running on an edge worker, and message types shared between the two sides. From Embedded Swift and Wasm to an increasingly capable cross-platform toolchain, Swift continues to expand its reach beyond Apple platforms.

At the language level, the recently accepted Iterable is also worth watching. Sequence produces independent element values one by one during iteration, but this model doesn’t work for data structures such as Span and InlineArray that may contain non-copyable elements. Iterable allows elements to be borrowed rather than copied during iteration, giving these data structures a natural way to be traversed as well. It may look like just another iteration abstraction, but it is also another sign of Swift’s ownership capabilities gradually moving from the language’s lower levels into everyday API design.


OpenSwiftUI on ESP32-C3

The Swift update above showed how Swift continues to push beyond the boundaries of Apple platforms, and a recent experiment by OpenSwiftUI developer Kyle Ye provides a very tangible example of that trend. After receiving an ESP32-C3 development device from TraeAI, Kyle completed his first Embedded Swift project: deploying an embedded version of OpenSwiftUI to this RISC-V-based microcontroller. On its 240 × 320 LCD, he built interfaces using familiar APIs such as View, @ViewBuilder, Text, Image, VStack, HStack, and ZStack. Even @State can respond to physical button input and trigger UI updates.

The experiment uses Embedded Swift to compile native RISC-V code, with OpenSwiftUI handling view composition and layout before passing drawing through a thin rendering boundary to LVGL and the underlying hardware. In other words, a lean but complete UI pipeline has been established, from declarative views and layout calculation to state updates and final pixel output.


Multiplatform Swift, with C++ dependencies via XCFramework, apt and vcpkg

Whether a Swift application can truly become cross-platform often depends on whether its underlying C/C++ dependencies can make the journey as well. Harald Achitz uses his own ZeroMQ Swift bindings as an example to show how a Swift/C++ project targeting macOS, Linux, and Windows can organize its native dependencies: XCFrameworks on Apple platforms, system packages on Linux, and vcpkg to install ZeroMQ on Windows.


Connecting two iOS simulators over BLE

CoreBluetooth is completely unavailable in the iOS Simulator, which has long made BLE app development and testing dependent on physical devices. While developing BLESwift 2.0, Kyle Browning took a different approach: instead of calling CoreBluetooth, the central and peripheral devices in the Simulator forward their operations over localhost TCP to bleswift-provider running on the Mac, which creates a “virtual radio.” This allows two Simulators to discover, connect to, read from, write to, and receive notifications from each other much like two real BLE devices. A passthrough mode can even use the Mac’s Bluetooth hardware to communicate with real BLE devices.

What interests me more than BLE itself is the testing pattern behind this approach: when the Simulator lacks a particular system or hardware capability, instead of scattering mocks throughout the app, we can establish a replaceable backend between system capabilities and business logic, then use a proxy process on the Mac to recreate a controllable external world. This design not only addresses missing system or hardware capabilities in the Simulator, but also makes features that once depended heavily on real-world environments much easier to bring into automated testing and CI.

Reorder all the things in SwiftUI

SwiftUI has long lacked a general-purpose API for drag-to-reorder interactions in arbitrary containers, a limitation that was finally addressed after WWDC 2026. Alexander Logan introduces SwiftUI’s new reordering APIs. With APIs such as reorderable and reorderableContainer, developers can directly declare which content can be reordered and its associated data model. Reordering is no longer limited to List, nor do developers need to manage drop positions and data updates themselves through DropDelegate. More importantly, the new APIs provide a higher-level interaction semantic, separating “reordering” from drag and drop as a specific implementation mechanism. Developers describe the intent that “this content can be reordered,” while the system can take greater responsibility for whether that interaction is performed with a mouse, touch, or another input method.


Building a sunburst diagram in Swift Charts

A Sunburst Diagram is a chart that uses concentric rings to represent hierarchical data—for example, moving from “Work” to “Development” and then to a specific project, with each outward ring representing a deeper level of detail. Matthaus Woolard demonstrates how to use Swift Charts’ SectorMark to start with a regular pie chart and gradually build a three-level sunburst diagram. The implementation also nicely demonstrates the flexibility of Swift Charts: when the framework doesn’t directly provide a particular chart type, Marks such as SectorMark can be treated as lower-level visualization primitives, allowing more complex charts to be constructed by calculating angular ranges and data mappings manually.

Tool

CoreDataBrowser: Quickly Inspect Local Data in the Simulator

When debugging Core Data or SwiftData apps, you typically need to locate the relevant data files buried deep within the Simulator’s directory hierarchy, then open them in a SQLite manager to inspect the data. CoreDataBrowser, developed by Csaba Turdesan, aims to simplify this process: after selecting the currently running Simulator, it automatically locates Core Data, SwiftData, and UserDefaults data sources in app containers and presents them together in a native macOS interface.

CoreDataBrowser supports browsing tables and records, searching and highlighting matches, and attempting to decode certain binary data (BLOBs) as NSKeyedArchive, JSON, Property List, or UTF-8 text. The tool is tiny (2.5 MB), and its source code is publicly available.


Thanks for reading Fatbobman’s Swift Weekly! This post is public so feel free to share it.


当 Mac mini 的价格不再 mini

网页版

上月底,苹果发布了新的 Mac mini 和 Mac Studio。除了强悍的性能更新,明显上涨的价格同样给人带来了不小的震撼。内存与存储成本上涨无疑是本轮涨价的重要原因,但在 AI 时代,开发者对硬件的需求也在悄然发生变化。更大的内存、更高的存储容量,不断推高我们心目中“够用配置”的标准,最终也让实际购买价格变得更加夸张。

过去几个月,开发中最让我头痛的一件事,是 MacBook Pro 风扇持续转动带来的噪音。过去多年的使用中,只有在少数高负载场景下,我才会明显意识到风扇的存在。但到了 AI Agent 时代,风扇常转几乎成了家常便饭。受限于机身空间和风扇尺寸,笔记本在持续高负载下产生的噪音,往往也比 Mac mini 这类桌面设备更容易让人感到不适。

与此同时,我发现 MacBook 在自己的工作流中似乎也没有以前那么不可替代了。除非有特殊需要,短途出差时,手机和平板已经足以应付不少 Vibe Coding 场景。即便仍然需要一台笔记本,一台更轻、配置更低的设备似乎也完全够用。因此,我开始认真考虑把主力开发设备从 MacBook Pro 转移到 Mac mini 或 Mac Studio 上。

问题随之而来:作为主力开发设备,内存容量必然是一道硬门槛。尽管我几乎没有运行本地 LLM 的需求,但既然是一次设备更新,新机器的内存至少应该明显高于当前的 64GB,才能让我感受到足够的升级价值。如此一来,采用 M6 或 M5 Pro 的 Mac mini 基本就被排除了,剩下的选择只有 M5 Max 和 M5 Ultra 的 Mac Studio。

有趣的是,两款机型在 64GB 之上的下一档内存分别是 128GB 和 96GB,而最终价格却相差无几。一个给更多内存,一个给更强芯片。即便我平时并不算有选择困难,这次也确实有些犯难。

与此同时,OpenClaw 的风行让不少原本并不关注 Mac mini 的消费者开始将目光投向这台小机器。据报道,OpenAI 也采购了数万台 Mac mini 和 Mac Studio,用于强化学习和 Computer-use Agent 的训练。AI 带来的需求增长一度远超苹果的预期,再加上内存供应和先进制程产能的压力,让 Mac mini 和 Mac Studio 在过去几个月一直处于供不应求的状态。新一代产品发布之后,想要尽快拿到自己心仪的配置,依然不是一件容易的事。

AI 带来的效率提升或许还没有在整个社会中充分显现,但它对算力、内存和存储资源的争夺,已经率先反映到了硬件市场。从零部件到整机,大量消费级硬件都在承受新的价格压力。过去那种隔几年用差不多的钱,就能买到一台明显更强电脑的更新节奏,至少在现阶段似乎越来越难维持了。

但更有意思的是,我们又不能把这一切完全归咎于涨价。AI 在推高硬件成本的同时,也改变了我们的开发方式,并悄悄抬高了我们对一台“够用电脑”的定义。硬件变贵了,我们想要的也更多了。

希望未来某一天,我们还能找回那个不用做太多心理建设,就能轻松选购一台 Mac mini 的时代。

前一期内容全部周报列表

如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 Buy Me a Coffee 支持我的创作。

原创

SwiftData:优化从建模开始

数据集一大,SwiftData 的列表就开始卡。这是这几年里我听到最多的性能抱怨。开发者的第一反应通常会指向 SwiftUI 的 List。它确实有责任,但并非最主要的问题。进一步分析会发现,真正拖垮性能的不只是加载时间,巨大的内存占用同样不容忽视。本文将聊聊 SwiftData 为什么会出现这些问题,以及优化为什么应该从数据建模开始。

SwiftData 中一些看似缺失的能力,或许本就是有意为之:通过减少暴露的 API 和逻辑层来降低学习曲线。因此,在优化 SwiftData 应用时,也应该适当放下 Core Data 时代形成的一些惯性思维。

近期推荐

十年终章:Swift Talk 宣布停更 (The End of Swift Talk)

在开始十年、完成 500 期节目后,⁠Chris Eidhof 和 ⁠Florian Kugler 宣布 Swift Talk 正式结束。从 2016 年 6 月开始,Swift Talk 几乎完整陪伴了 Swift 走向成熟的过程,也见证了 SwiftUI 从诞生到逐渐成为 Apple 平台 UI 开发核心框架的这些年。两人通过一系列深入而又充满实验性的节目,探索了 Swift、SwiftUI、布局、动画、并发以及大量很难在普通教程中看到的底层问题。官方表示,希望在今年年底让完整的 500 多期节目归档能够继续提供给社区。

对我而言,objc.io 和 Swift Talk 一直是 Swift 社区中非常特别的存在。Chris 和 Florian 很少满足于告诉开发者一个 API “应该怎么用”,而是习惯通过实验、重构甚至重新实现,去追问框架为什么会这样工作。这种探索方式影响了许多 Swift 开发者,也包括我自己。感谢 Chris 和 Florian 这些年来为 Swift 社区投入的时间、知识与好奇心,也感谢 Swift Talk 留下的这份珍贵档案。


Swift 官方 8 月报 (What’s new in Swift: August 2026 Edition)

Swift 官方发布了 8 月生态月报,由 ⁠Simon Leeb 和 ⁠Dave Lester 整理,汇总了近期值得关注的社区项目、Package 更新和 Swift Evolution 进展。其中最让我感兴趣的是 Swift 在 Web 方向上的推进:Simon Leeb 展示了一个 ⁠Full-Stack Swift on Cloudflare Demo,浏览器端通过 ElementaryUI 和 WebAssembly 运行 Swift,后端则运行在 edge worker 上,两端还能共享消息类型。从 Embedded Swift、Wasm 到越来越完善的跨平台工具链,Swift 的使用边界正在继续向 Apple 平台之外扩展。

语言层面,刚刚获批的 ⁠⁠Iterable 也很值得关注。Sequence 在遍历时会逐个产生独立的元素值,但对于 SpanInlineArray 等可能包含 non-copyable 元素的数据结构,这套模型并不适用。Iterable 允许直接借用而非复制元素进行遍历,让这些数据结构也能拥有自然的遍历方式。它看起来只是一个新的遍历抽象,却也是 Swift ownership 能力逐渐从语言底层走向日常 API 设计的又一个体现。


在嵌入式设备上运行 OpenSwiftUI (OpenSwiftUI on ESP32-C3)

上面的 Swift 月报展示了 Swift 正在不断突破 Apple 平台的边界,而 OpenSwiftUI 开发者 ⁠Kyle Ye 最近的一次尝试,则给这个趋势提供了一个很直观的例子。在收到 TraeAI 赠送的 ESP32-C3 开发设备后,Kyle 完成了自己的第一个 Embedded Swift 项目:将 OpenSwiftUI 的嵌入式版本部署到这块采用 RISC-V 架构的微控制器上,并在 240 × 320 的 LCD 上使用我们熟悉的 View@ViewBuilderTextImageVStackHStackZStack 等 API 构建界面,甚至 @State 也能响应实体按键并触发界面更新。

这个实验利用 Embedded Swift 编译原生 RISC-V 代码,由 OpenSwiftUI 负责视图组合和布局,再通过一个很薄的渲染边界将绘制交给 LVGL 和底层硬件。换句话说,从声明式 View、布局计算、状态更新到最终像素输出,一套精简但完整的 UI 链路已经建立起来。


Swift 跨平台实践:多平台下的 C++ 依赖管理 (Multiplatform Swift, with C++ dependencies via XCFramework, apt and vcpkg)

一个 Swift 应用能否真正实现跨平台,很多时候取决于其背后的 C/C++ 依赖能否跟着跨平台。⁠Harald Achitz 以自己的 ZeroMQ Swift bindings 为例,展示了一个同时支持 macOS、Linux 和 Windows 的 Swift/C++ 项目如何组织原生依赖:Apple 平台使用 XCFramework,Linux 使用系统 package,Windows 则通过 vcpkg 安装 ZeroMQ。


在 iOS 模拟器间实现虚拟蓝牙通信 (Connecting two iOS simulators over BLE)

CoreBluetooth 在 iOS Simulator 中完全不可用,这让 BLE App 的开发和测试长期依赖真机。⁠⁠Kyle Browning 在开发 ⁠BLESwift 2.0 时换了一种思路:Simulator 中的中心设备(Central)和外围设备(Peripheral)不再调用 CoreBluetooth,而是通过 localhost TCP 将操作转发给运行在 Mac 上的 bleswift-provider,由它构建一个“虚拟无线电”。这样,两个 Simulator 就能像两台真实 BLE 设备一样完成发现、连接、读写和 notification,甚至还可以通过 passthrough 模式借用 Mac 的蓝牙,与真实 BLE 设备通信。

比 BLE 本身更让我感兴趣的是这种测试范式:当 Simulator 缺少某项系统或硬件能力时,不一定要在 App 内到处添加 mock,而是可以在系统能力与业务代码之间建立可替换的 backend,再通过 Mac 上的代理进程重建一个可控的外部世界。这种设计不仅解决了“Simulator 缺少某些系统或硬件能力”的问题,也让原本高度依赖真实环境的功能更容易进入自动化测试和 CI。

探索 SwiftUI 全新的任意容器拖拽排序 API (Reorder all the things in SwiftUI)

SwiftUI 长期以来没有提供在任意容器中实现拖拽排序的通用 API,这个遗憾在 WWDC 2026 后得到了解决。⁠⁠Alexander Logan 介绍了 SwiftUI 新的 reordering API。通过 reorderablereorderableContainer 等,开发者可以直接声明哪些内容可以被重新排序以及对应的数据模型,让拖拽排序不再局限于 List,也不必自己通过 DropDelegate 管理拖拽位置和数据更新。更重要的是,新 API 提供了更高层的交互语义,将“reordering”从 drag & drop 这一具体实现方式中抽离出来。开发者描述的是“这些内容可以重新排序”,至于通过鼠标、触控还是其他输入方式完成操作,则可以更多地交给系统处理。


Swift Charts 进阶:如何绘制多层旭日图 (Building a sunburst diagram in Swift Charts)

旭日图(Sunburst Diagram)是一种用同心圆环展示层级数据的图表,例如从“工作”到“开发”,再到某个具体项目,越向外代表越细的数据层级。⁠⁠Matthaus Woolard 展示了如何利用 Swift Charts 的 SectorMark,从普通饼图开始,逐步构建一个包含三层数据的旭日图。这个实现也很好地展示了 Swift Charts 的灵活性:当框架没有直接提供某种图表时,可以将 SectorMark 等 Mark 视为更基础的可视化原语,通过自行计算角度区间和数据映射来构建更复杂的图表。

工具

CoreDataBrowser:快速查看 Simulator 中的本地数据

调试 Core Data 或 SwiftData 应用时,通常需要先在层层嵌套的 Simulator 目录中找到对应的数据文件,再用 SQLite 管理器打开并浏览数据。由 ⁠Csaba Turdesan 开发的 CoreDataBrowser 尝试把这个过程变得简单:选择当前启动的模拟器后,它会自动查找应用容器中的 Core Data、SwiftData 以及 UserDefaults 数据源,并通过原生 macOS 界面统一呈现。

CoreDataBrowser 支持查看表与记录、搜索并高亮匹配内容,也能对部分二进制数据(BLOB)尝试解析 NSKeyedArchive、JSON、Property List 和 UTF-8 文本。工具体量很小(2.5 MB),并且⁠源码公开

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论