Fatbobman's Swift Weekly #112
When AI Makes "Seeing Is Believing" Impossible
When AI Makes “Seeing Is Believing” Impossible
Nearly thirty years have passed since I graduated from college. Most of my classmates are now fully absorbed in their careers and families, so our alumni chat stays quiet for long stretches of time. But last Thursday night, an unexpected burst of activity suddenly broke the silence.
A classmate who hadn’t appeared in over a decade rejoined the conversation, saying his family was going through a difficult situation and asking if anyone could help. Almost immediately, doubts were raised—was it really him? Many of my former classmates work in legal professions, and their instincts tend to be finely tuned to anything that feels off.
We went through the usual steps: voice calls, video chats, back-and-forth questions. Still, some remained unconvinced. “AI makes impersonation way too easy now. Video and voice aren’t enough anymore.”
It wasn’t until more personal details surfaced—shared memories, old nicknames, inside jokes known only to our class—that everyone finally felt reassured. Once his identity was confirmed, help arrived quickly, and the immediate crisis was resolved.
Strictly speaking, it’s hard to blame anyone for being suspicious. When a single smartphone can “swap faces” or “alter voices,” seeing is believing no longer holds up. Social media is flooded with AI-generated oddities, and our tolerance for the absurd has quietly risen. Whose pet doesn’t talk or cook online these days? And if a UFO actually landed one afternoon, people might not be surprised at all—our threshold for the unknown has been reshaped.
This shift has brought a new kind of anxiety:
We once worried about not getting information fast enough or broadly enough; now we worry about whether the information is even real. “Trusted sources” have become a scarce commodity.
And no, AI shouldn’t shoulder the blame alone. It remains a tool. The ones exploiting it for deception are still people—the tactics have simply evolved, and the cost of lying has dropped dramatically.
Against this backdrop, rebuilding truth and trust becomes increasingly difficult.
Perhaps we’ll need to “fight fire with fire”: digital signatures, trusted timestamps, blockchain-based verification. None of these are perfect solutions, but they may be meaningful paths forward.
My mother used to tell me when I was young: “Doing good is like climbing uphill; doing harm is like falling off a cliff.”
The same is true of trust—infinitely harder to rebuild than to destroy, which is precisely what makes it precious.
Previous Issue|Newsletter Archive
This Week’s Sponsor
Need to debug HTTPS on your iPhone?
Try Proxyman! The best-in-class macOS that helps you capture/debug HTTP(s) with a few clicks. Support iOS devices and Simulator.
🎉 Black Friday Offer – 30% OFF this week only! Get Started Now →
Recent Recommendations
Deep Dive into iMessage: Behind the Making of an Agent
As Apple ecosystem developers, we often face a subtle paradox: the system possesses powerful capabilities, but these aren’t necessarily exposed to developers through public APIs. iMessage is a prime example—deeply integrated into iOS and macOS as a core communication tool for users, yet it has never provided automation interfaces for developers. LingJueYa, the author of imessage-kit, shares his exploration journey in building this tool. The core challenges almost all stem from the Apple platform itself: parsing timestamps with a 2001 epoch, recovering NSAttributedString content from binary plists, safely accessing resources within macOS’s sandbox system, and working with AppleScript—a venerable automation mechanism.
2025: The Year SwiftUI Died
Jacob Bartlett‘s provocatively titled article presents a discussion-worthy perspective: 2025 might mark a turning point for SwiftUI, rather than its peak. His core argument centers on Apple introducing the @Observable macro and updateProperties() method to UIKit, giving it modern state management capabilities, while the maturation of AI-assisted programming tools has dramatically reduced the cost of writing UIKit code (whereas AI’s understanding of SwiftUI’s declarative paradigm remains insufficient).
Apple’s long-term commitment to SwiftUI isn’t going anywhere — especially given its natural advantages in multi-platform adaptation. Meanwhile, the rise of AI has made it easier for many developers who started with SwiftUI to lean on UIKit when they need to fill performance or capability gaps. In practice, the choice for most adults isn’t either-or, but using both together in the most effective way.
Automatic Property Observation in UIKit with @Observable
UIKit officially introduced native support for Swift Observation in iOS 26. When you read properties of an @Observable object in updateProperties(), UIKit automatically tracks these dependencies and refreshes the corresponding views on-demand when data changes. Natalia Panferova demonstrates the convenience of this feature for cross-framework data sharing through a practical case mixing UIKit and SwiftUI. The article also introduces the iOS 18 backward compatibility solution: add the UIObservationTrackingEnabled key to Info.plist and place the update logic in viewWillLayoutSubviews() to achieve the same effect.
How SwiftData Represents AttributedString in Core Data Storage
Although AttributedString itself conforms to Codable, developers previously couldn’t use it directly as a property in SwiftData models. This restriction was finally lifted in iOS 26—Apple clearly opened a “special channel” for it, and now it can be stored directly like basic types such as Int and String. Oleksii Oliinyk, author of DataScout for SwiftData (a SwiftData database analysis app), encountered related crashes while maintaining the tool and took the opportunity to deeply analyze the implementation mechanism behind it.
SwiftData’s ability to allow developers to use Codable-conforming types as model properties is itself a powerful feature. However, its underlying handling may differ from what many people expect. In “Considerations for Using Codable and Enums in SwiftData Models,” I provide a more systematic introduction to SwiftData’s Codable conversion logic and potential pitfalls. Additionally, if you need to save AttributedString before iOS 26, you can refer to this thread on Apple’s developer forums.
Introducing AnyLanguageModel: One API for Local and Remote LLMs on Apple Platforms
AnyLanguageModel is a unified Swift LLM interface library developed by Mattt. We introduced its core concept in Issue 109. Building on Foundation Models’ API design, the library maintains a familiar developer experience while uniformly supporting multiple model providers, including local models (Core ML, MLX, llama.cpp, Ollama) and cloud models (OpenAI, Anthropic, Google Gemini, etc.), significantly reducing the integration burden across different APIs and execution methods, and making it easier to explore open-source models.
In this article, Mattt further introduces AnyLanguageModel’s design philosophy, cross-backend capability abstraction, and how Swift 6.1 package traits help control dependency size. Notably, while Apple currently doesn’t provide image input capability in Foundation Models, AnyLanguageModel has already added this functionality for models like Claude, enabling vision-language scenarios to work smoothly on Apple platforms.
Approachable Concurrency and MainActor by Default
Regardless of how things ultimately unfold, Approachable Concurrency introduced in Swift 6.2 is destined to leave a significant mark in Swift’s history. It significantly reduces the mental burden of concurrent programming in certain scenarios, but has also left many developers feeling “more confused the more it’s explained.”
In Approachable Concurrency in Swift 6.2: A Clear Guide, Antoine van der Lee provides a systematic overview of the relevant proposals and new behaviors.
After conducting extensive research and sharing about these features, Matt Massicotte emphasizes in his latest article MainActor by Default: at least for now, he won’t enable Default actor isolation = MainActor in his projects, because “understanding why MainActor is needed is far simpler than understanding why or how to remove it.”
However, one thing is crystal clear: MainActor by Default aligns perfectly with embedded platforms. In Embedded Swift Improvements Coming in Swift 6.3, Doug Gregor and Rauhul Varma further demonstrate the improvement direction and motivation for Swift 6.3 on embedded platforms.
How to Build Scalable White-Label iOS Apps: From Multi-Target to Modular Architecture
A White-Label product refers to a flexible, reusable app framework that can be deployed across different clients, with customizable branding and feature configurations (such as a universal restaurant ordering app template). Pawel Kozielecki systematically outlines the evolution of iOS White-Label applications in this comprehensive article, dividing it into three stages: basic branding customization, custom UI/UX, and full modularization. Building on this foundation, he compares three common implementation strategies—multi-target, resource replication, and modular architecture—and points out that as the number of clients and differentiation requirements grow, only modular architecture can truly scale long-term and avoid maintenance chaos. The article also discusses key challenges in scaling white-label projects, including App Store review, code signing, resource and configuration layering, testing, and CI, all with abundant practical details.
Tools
QuickLayout: Declarative UIKit Layout Library
Since UIKit can now seamlessly integrate Observation, it’s no surprise that writing layout code in SwiftUI style is also possible. QuickLayout, developed by Constantine Fry, provides exactly this capability and has been used by Meta in Instagram’s core features. You can lay out views directly like this:
import QuickLayout
@QuickLayout
class MyCellView: UIView {
let titleLabel = UILabel()
let subtitleLabel = UILabel()
var body: Layout {
HStack {
VStack(alignment: .leading) {
titleLabel
Spacer(4)
subtitleLabel
}
Spacer()
}
.padding(.horizontal, 16)
.padding(.vertical, 8)
}
}UIKit and SwiftUI were never opposites, but rather two UI thinking models that can learn from each other. Currently, SwiftUI’s advantages lie in abstraction and consistency, while high performance, fine-grained control, and toolchain support remain UIKit’s strengths.
SettingsKit
Nearly all apps need a settings interface. While not difficult to write, maintenance costs rise as options multiply. SettingsKit, developed by Aether, was created to address this. It enables SwiftUI developers to quickly build scalable, consistently styled settings interfaces with built-in search capabilities, featuring multiple styles including grouped, card, and sidebar layouts—ideal for medium to large settings modules.
KurrentDB-Swift
Kurrent (formerly EventStoreDB) is a database specifically designed for event storage. It not only saves the current state of a system but also maintains a complete record of every change in its history, making it ideal for scenarios requiring strong traceability such as finance, logistics, retail, e-commerce, and SaaS. As a Swift client library for KurrentDB, KurrentDB-Swift developed by Grady Zhuo supports Swift 6, async/await streaming subscriptions, and event reading, filling a long-standing gap in the Swift ecosystem for mature Event Sourcing tools.
Thanks for reading Fatbobman’s Swift Weekly! This post is public so feel free to share it.
毕业 30 年同学群:一场 AI 引发的“真假难辨”危机
大学毕业快三十年了,同学们大多忙于事业与生活,群里常年冷清。但上周四晚上,一阵久违的热闹突然打破了沉寂。
一位十几年未露面的同学重新加入群聊,说家里遭遇了变故,向大家求助。很快就有人提出质疑——这真的是本人吗?毕竟群里多数人从事法律相关工作,职业敏感度让他们对任何异常格外警觉。
语音通话、视频聊天,一轮轮验证下来,仍有人不放心:“现在 AI 造假太容易了,光凭这些可不够。”直到更多细节被摆上桌面——共同经历、内部昵称、只有我们知道的旧梗——大家才最终确认身份,随即伸出援手,帮助他度过暂时的难关。
严格来说,并不能怪大家变得多疑。在如今一部手机就能“换头”“变声”的时代,“眼见为实”早已不再成立。社交媒体上布满了由 AI 生成的各种离奇情景,人们对“离谱视频”的耐受度不断被拉高:谁家的宠物不会说话、做饭呢?也许哪天真看到 UFO 降落,都不会再令人惊讶——我们对未知的恐惧阈值,正在被悄悄重塑。
随之而来的,是一种新的信息焦虑:过去担心的是获取不及时、不全面;如今担心的是获取的内容是否真实。“可信来源”,正在变成一件稀缺品。
当然,这一切不能算在 AI 头上。AI 本质上只是工具,真正利用它造假、行骗的仍然是人,只是欺骗的方式变了、成本更低了。
在这种背景下,重拾真实与信任,只会变得愈发困难。
或许,最终仍需“魔法打败魔法”:数字签名、可信时间戳、区块链验证……它们未必是完美解法,但至少是值得探索的方向。
从小我母亲就常说:“从善如登,从恶如崩”。
信任亦如此——重建远比摧毁艰难,却也正因如此才显得格外珍贵。
如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 爱发电,Buy Me a Coffee 支持我的创作。
本期赞助
需要在 iPhone 上调试 HTTPS?
试试 Proxyman!这是一款顶级的 macOS 应用,只需点击几下,即可轻松捕获和调试 HTTP(s) 流量。支持 iOS设备和模拟器。
🎉 黑五特惠 — 本周限时 7 折! 立即试用 →
近期推荐
深入 iMessage 底层:一个 Agent 是如何诞生的
作为 Apple 生态的开发者,我们常常会面对一个微妙的悖论:系统本身具备强大的能力,但这些能力并不一定以公开 API 的形式向开发者开放。iMessage 正是其中的典型 —— 它深度融入 iOS 与 macOS,是用户日常沟通的核心载体,却始终没有提供可供开发者使用的自动化接口。imessage-kit 的作者 LingJueYa,分享他在构建这一工具时的探索路径。但其核心挑战几乎都来自 Apple 平台本身:解析以 2001 为纪元的时间戳、从二进制 plist 中恢复 NSAttributedString 内容、在 macOS 的沙盒体系下安全地读取资源、以及与 AppleScript 这种历史悠久的自动化机制打交道。
SwiftUI 已死? UIKit 的回归之路 (2025: The Year SwiftUI Died)
Jacob Bartlett 的这篇文章标题颇具挑衅意味,他提出了一个值得讨论的观点:2025 年也许是 SwiftUI 的拐点,而不是它的巅峰。核心论点在于,苹果将 @Observable 宏和 updateProperties() 方法引入 UIKit,使其具备了现代化的状态管理能力;同时,AI 辅助编程工具的成熟极大降低了编写 UIKit 代码的成本(而 AI 对 SwiftUI 这种声明式范式的理解仍显不足)。
苹果对 SwiftUI 的长期投入不会动摇,尤其考虑到它在多端适配上的天然优势。与此同时,AI 的普及也让许多以 SwiftUI 入门的开发者更容易使用 UIKit 来补齐性能或能力上的不足。选择不一定要非此即彼,可以将两者结合起来用得更好。 这样更好吧
UIKit 中的视图自动刷新 (Automatic property observation in UIKit with @Observable)
UIKit 在 iOS 26 中正式引入了对 Swift Observation 的原生支持。当你在 updateProperties()中读取 @Observable 对象的属性时,UIKit 会自动追踪这些依赖关系,并在数据变化时按需刷新对应视图。Natalia Panferova 通过一个混合 UIKit + SwiftUI 的实际案例展示了这一特性在跨框架数据共享时的便利性。文章还介绍了 iOS 18 的向下兼容方案:在 Info.plist 中添加 UIObservationTrackingEnabled 键,并将更新逻辑放在 viewWillLayoutSubviews() 中即可实现相同效果。
SwiftData 对 AttributedString 的原生支持 (How SwiftData Represents AttributedString in Core Data Storage)
尽管 AttributedString 本身符合 Codable,但过去开发者并不能直接在 SwiftData 模型中将其作为属性使用。这一限制终于在 iOS 26 中被解除 —— 苹果显然为它开了一条“特别通道”,如今它已经可以像 Int、String 这样的基础类型一样直接存储了。DataScout for SwiftData(SwiftData 数据库分析应用)的作者 Oleksii Oliinyk 在维护工具时遭遇了相关的崩溃问题,并顺势深入分析了其背后的实现机制。
SwiftData 允许开发者将符合 Codable 协议的类型作为模型属性,这本身是一项十分强大的能力。但它的底层处理方式可能与许多人预想的并不相同。我在《在 SwiftData 模型中使用 Codable 和枚举的注意事项》中对 SwiftData 的 Codable 转换逻辑与潜在陷阱做了更系统的介绍。此外,如果你需要在 iOS 26 之前保存 AttributedString,可以参考苹果开发者论坛上的这个帖子。
AnyLanguageModel:统一 Apple 平台的 LLM 接口 (Introducing AnyLanguageModel: One API for Local and Remote LLMs on Apple Platforms)
AnyLanguageModel 是由 Mattt 开发的统一 Swift 大模型接口库,我们已在第 109 期周报中介绍过其核心理念。该库以 Foundation Models 的 API 设计为基础,在保持开发者熟悉的使用方式的同时,统一支持多种模型提供方,包括本地模型(Core ML、MLX、llama.cpp、Ollama)以及云端模型(OpenAI、Anthropic、Google Gemini 等),大幅降低了跨 API、跨运行方式所带来的集成负担,也让探索开源模型变得更容易。
在这篇文章中,Mattt 进一步介绍了 AnyLanguageModel 的设计思路、跨后端的能力抽象及 Swift 6.1 package traits 在控制依赖体积中的作用。值得一提的是,尽管苹果当前尚未在 Foundation Models 中提供图像输入能力,AnyLanguageModel 已为 Claude 等模型补上这一功能,使视觉-语言场景也能在 Apple 平台上顺利落地。
Approachable Concurrency 与 MainActor by Default
无论最终走向如何,Swift 6.2 中引入的 Approachable Concurrency 注定会在 Swift 发展史上留下浓重的一笔。它在某些场景下显著降低了并发编程的心智负担,但也让不少开发者感到“越解释越困惑”。
在 Approachable Concurrency in Swift 6.2: A Clear Guide 一文中,Antoine van der Lee 中对相关提案和新行为进行了系统梳理。
Matt Massicotte 在对这些功能进行了详尽研究和分享后,他在最新文章 MainActor by Default 中强调:至少在现阶段,他不会在项目中启用 Default actor isolation = MainActor,因为“理解为何需要 MainActor,要比理解为何删除它更容易”。
不过有一点已经十分明确:MainActor by Default 与嵌入式平台非常契合。在 Embedded Swift Improvements Coming in Swift 6.3 一文中,Doug Gregor 和 Rauhul Varma 则进一步展示了 Swift 6.3 在嵌入式平台上的改进方向与动机。
构建可扩展的白标 iOS 应用 (How to Build Scalable White-Label iOS Apps: From Multi-Target to Modular Architecture)
白标产品(White-Label)指的是一个架构灵活、可在不同客户之间复用的通用 App 框架,能够按需更换品牌皮肤与功能配置(例如通用的订餐 App 模板)。Pawel Kozielecki 在这篇长文中系统梳理了 iOS White-Label 应用的演进路线,将其划分为三个阶段:基础品牌定制、自定义 UI/UX,以及完全模块化。在此基础上,他对比了三种常见实现策略——多 Target、资源复制、模块化架构,并指出随着客户数量与差异化需求增长,真正能够长期扩展、避免维护失控的方案只有模块化(Modular Architecture)。文章还结合大量实战细节,讨论了审核、签名、资源与配置分层、测试与 CI 等白标项目在规模化过程中的关键挑战。
工具
QuickLayout: 声明式 UIKit 布局库
既然 UIKit 已经可以无缝集成 Observation 了,那么以 SwiftUI 风格编写布局代码也就不足为奇了。由 Constantine Fry 开发的 QuickLayout 便提供了这样的能力,其已被 Meta 在 Instagram 的核心功能中使用。你可以直接以如下的方式进行布局:
import QuickLayout
@QuickLayout
class MyCellView: UIView {
let titleLabel = UILabel()
let subtitleLabel = UILabel()
var body: Layout {
HStack {
VStack(alignment: .leading) {
titleLabel
Spacer(4)
subtitleLabel
}
Spacer()
}
.padding(.horizontal, 16)
.padding(.vertical, 8)
}
}UIKit 和 SwiftUI 从来不是对立面,而是两套可互相借鉴的 UI 思维模型。现阶段 SwiftUI 的优势在于抽象与一致性,而高性能、精细控制、工具链支持等仍是 UIKit 的特长。
SettingsKit
几乎所有应用都需要设置界面,虽然编写难度不高,但当选项不断增加时,维护成本也会随之上升。Aether 开发的 SettingsKit 正是为此而生。它让 SwiftUI 开发者可以快速构建一个可扩展、样式统一、并带有搜索能力的设置界面,并内置分组、卡片、侧栏等多种风格,适用于中大型设置模块的搭建。
KurrentDB-Swift
Kurrent(原 EventStoreDB)是一款专门用于事件存储的数据库,它不仅保存系统的最新状态,还能完整记录每一次变化的历史,非常适用于金融、物流、零售、电商、SaaS 等需要强可追溯性的场景。作为 KurrentDB 的 Swift 客户端库,由 Grady Zhuo 开发的 KurrentDB-Swift 支持 Swift 6、async/await 流式订阅与事件读取,补上了 Swift 生态在 Event Sourcing 领域长期缺乏成熟工具的空白。


