Fatbobman's Swift Weekly #150
AI Wanted to Give Up. The Human Didn’t.Recently, while debugging an issue in the Intel Xe GPU driver, Linus Torvalds went through what he himself called a “debug session from hell.” The eventual fix was almost absurdly simple: changing a The most interesting part of the story, however, isn’t that “AI helped Linus fix a Linux kernel bug.” It’s that the AI tried to give up several times along the way. At one point, it explicitly told Linus that the problem was “impossible and unsolvable” and suggested ending the investigation. Linus rejected that conclusion. At his insistence, the AI kept faithfully carrying out new tasks despite repeatedly concluding that the problem could not be solved, and together they eventually traced the cause to something that required changing just a single line of code. This offers a revealing glimpse into the rather subtle relationship between humans and AI today. As agents become more capable, we can delegate increasingly complete pieces of work to them: reading code, forming hypotheses, writing debugging tools, running validations, and even adjusting the next step based on new evidence. Much of the repetitive work that developers once had to perform themselves is being compressed, gradually pulling humans away from the details of execution. But that doesn’t mean the human role is shrinking at the same pace. Quite the opposite. As AI begins to participate in analysis, make recommendations, and even offer judgments such as “this problem cannot be solved,” the responsibilities that remain with humans become clearer: deciding what is worth pursuing, knowing when to trust AI, and recognizing when to reject its conclusions. Not every instance of human persistence will end as neatly as this one did. But sometimes, the reason to keep going just a little longer should not be so easily erased by an AI saying, “impossible.” Previous Issue|Newsletter Archive 📢 Sponsor Fatbobman’s Swift WeeklyPromote your product to Swift & iOS developers across: - Blog: 50,000+ monthly visitors Perfect for developer tools, courses, and services. Enjoyed this issue? Buy me a coffee ☕️ OriginalFrom Using AI to Delegating Work to AI: Some ThoughtsWhen a task already has clear goals, boundaries, and acceptance criteria, how can we truly hand it over to AI? The more complex the work an Agent can handle, the more prominent this question becomes. Model outputs can vary; as context grows longer, goals and rules may gradually fade; splitting work across multiple contexts introduces information loss and handoff drift. Having another model review the result does not necessarily mean things will naturally converge. All of these issues ultimately point to the same concept: delegatability. This article presents some of my thoughts on AI delegatability: whether the scope of execution remains stable, whether the results can be trusted, whether the required investment is predictable, and when human intervention is necessary. Rather than pursuing the best possible result from any single run, I am more interested in how clear boundaries, acceptance criteria, externalized authoritative records, and sensible human-AI division of labor can help Agents remain stable across longer and more complex tasks, while ensuring that failures can be detected and corrected. The article concludes with the Task-Driven workflow I currently use, showing how these principles can be applied in practical AI-assisted development. Recent RecommendationsWhat is a package registry?After Swift Package Index joined Apple, the two announced that they would work together to build a package registry for the Swift community. But how does a package registry differ from SwiftPM, which we have used for years, and the Package Index, which helps us discover and evaluate packages? Dave Verwer starts with SwiftPM’s current Git-based dependency model: traditional dependencies require fetching source code from a Git repository and checking out the appropriate version, while a registry can distribute published source archives directly through package IDs, without carrying Git history, while also making published versions immutable. But the significance of a registry goes beyond making package downloads more lightweight. More importantly, it introduces a formal package publishing model and raises broader questions around developer identity, package scope ownership, version publishing, and software supply chain security. This article offers both a concise introduction to how Package Registry works and useful background for understanding the Swift package infrastructure that Apple and Swift Package Index are preparing to build. Handling CoreBluetooth Timeouts and Task Cancellation CorrectlyWrapping CoreBluetooth’s delegate APIs in async/await with ilawsonlu explores these practical problems and explains how to build a more complete timeout and cancellation mechanism for asynchronous CoreBluetooth wrappers. The article clearly distinguishes between cancelling a Swift Task and cancelling the underlying operation, while the open-source library ArcBLEKit demonstrates an approach to wrapping traditional delegate APIs in more robust Swift Concurrency APIs. What Is CloudKit? Apple’s Backend ExplainedCloudKit is an important yet often underestimated piece of infrastructure in the Apple ecosystem. From simple cross-device data synchronization to shared data and public databases, it allows developers to provide their apps with backend capabilities deeply integrated with Apple platforms through iCloud, without having to build and maintain their own servers. With both SwiftData and Core Data able to integrate directly with CloudKit, many developers are already using it without necessarily interacting with the CloudKit API itself. Starting from the basic requirements of a backend, Sean Allen systematically introduces CloudKit’s private, shared, and public databases, along with core concepts such as Container, Record, and Schema, and compares three approaches: SwiftData, Core Data, and using the CloudKit API directly. The article does not shy away from CloudKit’s limitations, including its dependence on the Apple ecosystem and iCloud, schema migration, cross-platform support, and constraints around complex server-side logic. OCR Doesn’t Give You Text. It Gives You a MapVision OCR does not return a neatly organized block of text. Instead, it gives you a collection of observations with bounding boxes: array order does not represent reading order, word boundaries do not inherently exist, and relationships between fields cannot simply be inferred from what comes before or after. While developing a record-sleeve scanning feature, Wesley Matlock encountered four bugs in a single day that appeared different but all stemmed from the same mistaken assumption. Through these real-world cases, the article shows how to use coordinates to determine reading order, reconstruct word boundaries from spacing, and associate fields through spatial proximity. Even more instructive is the author’s testing approach: saving bounding boxes exposed by real images as fixtures, using pure geometric data to lock down each layout assumption, while retaining the original photos for end-to-end tests. As the title says, OCR does not give you text—it gives you a “map.” The actual text structure has to be reconstructed from spatial relationships. 6 ways to promote your app without spending a pennyFor indie developers, finishing an app is often only the first step. Getting more people to discover it can be even harder. Kickstart, created by Paul Hudson, outlines six promotional strategies in this article that require little to no financial investment: submitting to channels such as Indie App Showcase, cross-promoting with other indie developers through Kickstart Exchange, participating in communities where your target users gather, building your own mailing list, building in public, and continuously improving your App Store product page. In addition, MacStories’ Federico Viticci is looking for noteworthy new apps and app updates for his annual iOS 27 Review. If you are preparing an iOS 27 release, you can recommend your app to him via DM or email at ToolsAmethyst Vein: An Open-Source, Cross-Platform Local Persistence Framework with SwiftData-Style APIsDeveloped by Mia Koring, Amethyst Vein is a local-first Swift ORM built on SQLite and SQLCipher, with APIs clearly inspired by SwiftData. It aims to bring SwiftData-style @Model, @Query, relationships, and migration APIs to Apple platforms, Linux, Android, and Windows. The project uses explicit versioned migrations, an Identity Map, and field-level synchronization, while supporting both SwiftUI and SwiftCrossUI. DynamicNotch: Building Polished Notch and Screen-Edge Interactions for macOSDeveloped by Govi, DynamicNotch is a macOS Swift Package designed for developers to create SwiftUI interfaces attached to the edges of the screen. It can present recording status, media controls, build progress, action confirmations, and compact views similar to Dynamic Island. It properly handles safe areas, multiple displays, and the physical notch on MacBooks, supports all four screen edges, and can transition between compact and expanded states. DynamicNotch keeps its implementation deliberately focused: it handles geometry, clipping, positioning, and window presentation without imposing product-level logic such as gestures, notifications, or state management on developers. SwiftTUI: Building Terminal Interfaces the SwiftUI WayDeveloped by Adam Zethraeus, SwiftTUI is a terminal user interface framework for Swift developers. It brings SwiftUI’s declarative programming model to the terminal: developers can build interactive interfaces using What makes SwiftTUI interesting is not simply that it lets you “write TUIs in Swift.” The same view code can run in macOS, Linux, and Windows terminals, and can also be deployed to the browser, WASI, and native SwiftUI containers. The counter on its official website is itself a real SwiftTUI application, compiled to WebAssembly and running directly in the browser. Thanks for reading Fatbobman’s Swift Weekly! This post is public so feel free to share it. AI 想放弃了,人没有最近,Linus Torvalds 在调试一个 Intel Xe GPU 驱动问题时,经历了一场被他自己称为“debug session from hell”的漫长排查。最终的修复简单得有些不可思议:把一处 这个故事最有意思的地方并不是“AI 帮 Linus 修复了 Linux Kernel Bug”,而是 AI 在过程中数次想要放弃。它曾明确告诉 Linus,这个问题“impossible and unsolvable”,建议停止继续调查。Linus 没有接受这个判断。在他的坚持下,AI 虽然数次认为问题已经无法解决,却仍然忠实地执行新的任务,最终和他一起找到了那个只需要修改一行代码的原因。 这其实很好地展现了现阶段人与 AI 之间一种颇为微妙的关系。随着 Agent 能力不断增强,我们已经可以把越来越完整的工作交给 AI:阅读代码、提出假设、编写调试工具、执行验证,甚至根据新的结果不断调整下一步行动。过去需要开发者亲自完成的大量重复劳动正在被压缩,人也因此逐渐从具体的执行过程中抽离出来。 但这并不意味着人的作用正在以同样的速度缩小。恰恰相反,当 AI 开始参与分析、提出建议,甚至给出“这个问题无法解决”这样的判断时,人真正需要承担的职责反而变得更加清晰:决定什么值得做,判断什么时候应该相信 AI,又在什么时候拒绝它的结论。 尽管并非所有人类的坚持都会获得类似本次的圆满结果,但有时候,再坚持一下的理由,至少不应该被 AI 的一句“不可能”轻易抹去。 如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 Buy Me a Coffee 支持我的创作。 原创从使用 AI 到委托 AI:我的一些思考当一项工作已经有明确目标、边界和验收要求时,怎样把它真正交给 AI?Agent 能完成的工作越复杂,这个问题就越突出。模型的输出存在波动;上下文变长后,目标和规则可能逐渐淡化;拆进多个上下文,又会带来信息损失和交接偏移。让另一个模型复核,也不意味着结果一定会自然收敛。这些问题最终指向同一个词:可委托性。 本文是我对 AI 可委托性的一些思考:执行范围是否稳定,结果能否被信任,投入是否可以预期,以及什么时候需要人介入。相比追求某一次执行的最好结果,我更关心如何通过明确边界、验收标准、外置的权威记录以及合理的人机分工,让 Agent 在更长、更复杂的任务中保持稳定,并让失败能够被发现和纠正。文章最后也结合我目前使用的 Task-Driven 工作流,展示这些原则如何落实到实际的 AI 开发过程中。 近期推荐认识 Swift 包注册表 (What is a package registry?)Swift Package Index 加入 Apple 后,双方宣布将共同建设一个面向 Swift 社区的 package registry。但 package registry 与我们已经使用多年的 SwiftPM,以及用于发现和评估包的 Package Index,究竟有什么区别?Dave Verwer 从 SwiftPM 当前基于 Git 的依赖方式讲起:传统依赖需要从 Git 仓库获取源码并 checkout 对应版本,而 registry 可以通过 package ID 直接分发已经发布的源码 archive,无需携带 Git history,同时发布后的版本也具有不可变性。 不过,registry 的意义并不只是让 package 下载变得更轻量。更重要的是,registry 还引入了一套正式的 package publishing 模型,并进一步涉及开发者身份、package scope 所有权、版本发布以及软件供应链安全等问题。这篇文章既是一篇对 Package Registry 工作方式的简明介绍,也为理解 Apple 与 Swift Package Index 接下来准备建设的 Swift 包生态基础设施提供了很好的背景。 如何正确处理 CoreBluetooth 超时与 Task Cancellation用 ilawsonlu 围绕这些实际问题,介绍了如何为 CoreBluetooth 的异步封装建立更完整的 timeout 与 cancellation 机制,并明确区分「取消 Swift Task」与「取消底层操作」,同时通过开源库 ArcBLEKit 展示了将传统 delegate API 封装成更健壮的 Swift Concurrency API 的思路。 详解 CloudKit:Apple 生态的后端服务 (What Is CloudKit? Apple’s Backend Explained)CloudKit 是 Apple 生态中非常重要、却常常被低估的一块基础设施。从简单的跨设备数据同步,到共享数据和公共数据库,它让开发者无需自行搭建服务器,就能依托 iCloud 为 App 提供一套与 Apple 平台深度集成的后端能力。尤其随着 SwiftData 和 Core Data 都能够直接接入 CloudKit,许多开发者实际上已经在使用它,只是不一定需要直接面对 CloudKit API。 Sean Allen 从 backend 的基本需求出发,系统介绍了 CloudKit 的 private、shared 和 public database,以及 Container、Record、Schema 等核心概念,并比较了 SwiftData、Core Data 和直接使用 CloudKit API 三种接入方式。文章并没有回避它的边界,包括对 Apple 生态和 iCloud 的依赖、schema migration、跨平台能力以及复杂服务端逻辑的限制。 重新认识 OCR:它是空间地图,而非纯文本 (OCR Doesn’t Give You Text. It Gives You a Map)Vision OCR 返回的并不是一段已经组织好的文本,而是一组带有 bounding box 的 observations:数组顺序不代表阅读顺序、单词边界并不存在,字段之间的关系也不能简单通过前后位置判断。Wesley Matlock 在开发唱片封套扫描功能时,一天内连续遇到了四个看似不同、实则来自同一错误假设的 Bug。本文通过这些真实案例展示了如何利用坐标计算阅读顺序、根据间距恢复单词边界,并通过空间邻近关系关联字段。更值得借鉴的是作者的测试方式:将真实图片暴露出的 bounding box 保存为 fixture,用纯几何数据固定每一项布局假设,同时保留真实照片作为端到端测试。正如标题所说,OCR 给你的不是文本,而是一张「地图」,真正的文本结构需要从空间关系中重新构建。 独立应用零成本推广的 6 个策略 (6 ways to promote your app without spending a penny)对于独立开发者来说,写完 App 往往只是第一步,如何让更多人知道它可能更加困难。由 Paul Hudson 创建的 Kickstart 在这篇文章中整理了六种几乎不需要资金投入的推广方式:向 Indie App Showcase 等渠道投稿、通过 Kickstart Exchange 与其他独立开发者交叉推广、参与目标用户所在的社区、建立自己的邮件列表、Build in Public,以及持续优化 App Store 产品页面。 另外,MacStories 的 Federico Viticci 正在为年度 iOS 27 Review 寻找值得关注的新 App 和 App 更新。如果你正在准备 iOS 27 版本,可以通过 DM 或邮件 工具Amethyst Vein:跨平台、SwiftData 风格 API 的开源本地持久化框架由 Mia Koring 开发的 Amethyst Vein 是一个本地优先的 Swift ORM,采用 SQLite 与 SQLCipher 作为存储基础,API 则明显借鉴了 SwiftData。它试图把 SwiftData 风格的 @Model、@Query、关系和迁移 API 带到 Apple、Linux、Android 与 Windows。项目采用显式版本化迁移、Identity Map 和字段级同步,并同时支持 SwiftUI 与 SwiftCrossUI。 DynamicNotch:帮助开发者为 macOS 构建精致的刘海与屏幕边缘交互由 Govi 开发的 DynamicNotch 是一个专为开发者打造的 macOS Swift Package,用于创建贴附于屏幕边缘的 SwiftUI 界面,可呈现录音状态、媒体控制、构建进度、操作确认,以及类似 Dynamic Island 的紧凑视图。 它能妥善处理安全区域、多显示器和 MacBook 实体刘海,支持上下左右四个方向,也可以在紧凑与展开状态之间切换。DynamicNotch 的实现比较克制,只负责几何、裁剪、定位与窗口呈现,并未将手势、通知、状态管理等产品逻辑强加给使用者。 SwiftTUI:用 SwiftUI 的方式构建终端界面由 Adam Zethraeus 开发的 SwiftTUI 是一个面向 Swift 开发者的终端用户界面框架。它将 SwiftUI 的声明式编程模型带进终端:开发者可以使用 SwiftTUI 的有趣之处,不只是“用 Swift 写 TUI”。同一套视图代码还可以运行于 macOS、Linux 和 Windows 终端,并进一步部署到浏览器、WASI,以及原生 SwiftUI 容器;官网提供的计数器就是一个真实的 SwiftTUI 应用,经 WebAssembly 编译后直接运行在网页中。 Welcome to my blog Fatbobman's Swift Blog( 肘子的Swift记事本 )
|
