过去几个月,我一直在优化自己的 AI 工作流。尽管颇有进展,但在长任务中,始终缺乏一些可以量化的 benchmark 数据。得益于 AI 模型公司之间的竞争,不久前 OpenAI 解除了 5 小时的额度限制,这让我终于能够不间断地测试自己的一些想法,并比较不同方案在效果与性能上的差异。上周,我把两个 Pro 账户攒下的 6、7 次额度都用掉了,着实体验了一把“Token 自由”的感觉。
由于每一个测试通常都需要跑上至少几十分钟,在等待、观测的过程中,我经常会灵感涌动,脑子里不断冒出各种优化和调整方案。这就产生了一个奇怪的现象:旧版本的测试还在运行时,新版本的代码已经写完了。迭代速度彻底跑在了测试结果前面。尽管其中确实有一些改动颇见成效,但冷静后也不得不面对一个残酷的事实——许多自以为是的“灵感”其实只是想当然,并没有经过审慎的思考。
然而,在那种由“Vibe Coding”产生的虚假“心流”状态下,当时的我并没有意识到这一点。直到测试结果出现明显的劣化,我才猛地踩下刹车,开始认真反思。
AI 的确极大地缩短了我们验证一个 Idea 的时间,但这种便利也容易让人陷入盲区,忽略了在动手前对构想进行深入思考与逻辑梳理的过程。不能让低成本的“穷举测试”取代真正的思考。回过头来看,我们积累的直觉与经验,在否决或调整那些不切实际的构想时,效率往往远高于 AI 的盲目试错。
AI 是一个极其强大的工具,但它最该发挥作用的地方是辅助执行,而非代替思考。
近期推荐
厘清 SwiftUI 中的三大视图组修饰符 (Geometry, compositing and drawing groups in SwiftUI)
SwiftUI 中三个名字相近却职责迥异的修饰符——geometryGroup()、compositingGroup()、drawingGroup(),它们不仅容易被混淆,而且很多人也不知道它们的精妙作用。
Natalia Panferova 用三个具体场景逐一拆解:geometryGroup() 通过将插值机制上提,解决子视图动画缺少一致过渡状态的问题;compositingGroup() 为其上层的图形效果(如 opacity、blend mode)划定合成边界,使其把多个子层级当作一个整体处理,而非逐层分别作用;drawingGroup() 则是把多个层级栅格化(rasterize)为一张离屏图像(offscreen image),以空间换性能,代价是每次内容变化都要重新生成这张图。
用 Swift 6 并发机制合并 LLM 与遥测双数据流 (One TaskGroup, Two Live Streams: a Swift 6 LLM Benchmark)
Wesley Matlock 通过将所有可变运行状态收进一个 actor,从而将模型推理与系统遥测两条独立的异步流,安全合并为一个有序事件流。
token 计数、首 token 延迟、采样记录等所有运行时状态只存在于 actor 内部。在 execute 中,一个 withThrowingTaskGroup 同时跑两条逻辑——子任务(child task)消费遥测流(telemetry stream),按 500ms 节奏采样并生成 RunEvent;父任务(parent task)则顺序执行推理循环,每次 await 都是一个挂起点(suspension point),父任务让出时子任务才有机会运行,整个 actor 对外只暴露一个 AsyncThrowingStream。因为所有访问都经过 actor 隔离,交替执行永不冲突——零竞争不是靠自觉,是编译器直接证明的。
利用 HistoryObserver 构建 SwiftData 自定义同步 (Syncing SwiftData with a Custom Backend Using HistoryObserver)
几年前,苹果便给 SwiftData 提供了 SwiftData History 机制,该机制与 Core Data 的 Persistent History Tracking 类似,让开发者实时掌握来自不同源对同一个数据库造成的数据变更事件,但由于缺少一个与 SwiftData 设计理念贴近的简单入口,该功能的利用率并不高。在 WWDC 2026 上,苹果为 SwiftData 引入 HistoryObserver,让触发、增量读取变得非常简单。Mohammad Azam 展示了该能力在真实项目中的应用,通过 HistoryObserver 搭出完整的自定义单向同步管线。
文章围绕一个房间测量小应用展开:用 withContinuousObservation 监听变更计数触发同步,用持久化的 lastToken 做书签实现增量读取,再用 isDeleted 软删除配合 author 标签避免硬删除引发的递归自触发。Mohammad 对打造同步引擎时会踩的坑,逐一给出解法,并附带完整可跑的 GitHub 示例。
在 Swift 模块包中共享公开的资源符号常量 (Public asset symbol constants in Swift packages)
Xcode 会从 .xcassets 自动生成类型化的资源常量,比如 Color(.skyBlue) / Image(.logo),但这些常量是 internal 的,无法供其他 Swift 包使用,Xcode 既不提供 public 选项,也无法在 Package.swift 里关闭这套生成机制。
Ralf Ebert 把要跨包共享的资源放进 .xcassets 内的 Public/ 子目录,再用一个 Ruby 脚本扫描所有 **/*.xcassets/Public/,按包名生成一个嵌套 enum 的 <PackageName>+Generated.swift,把内部符号重新导出为 public——从而可以在其他库中通过 Image(.AppCommons.logo) 的方式来调用。
突破 Xcode 预览与 MCP 的沙盒限制 (Previews and MCP)
Xcode 27 提供的 MCP 接口一共暴露了 47 个工具,其中 RenderPreview 负责对 Preview 进行渲染与截图。但调用它的应用必须通过 xcrun mcpbridge 建立 STDIO 连接,这要求应用不能被沙盒化(sandboxed)——直接与上架 Mac App Store 的规则冲突。
Amy Delves 的解法是引入一个独立的、未沙盒化的 XPC 服务专门与 Xcode MCP 对话,主 App 本身仍保持沙盒化,两者通过 XPC 通信;渲染结果由 helper 服务读取后内联传回,从而绕开主 App 无法访问沙盒外文件路径的限制。
我找到了解决 App Store Connect 登录 Bug 的 workaround (I found a workaround for an App Store Connect bug)
不少开发者都遇到过 App Store Connect 的一个 Bug:在已登录状态下页面仍会跳转回 /login。Jeff Johnson 在与 Apple 沟通无果后,用 Chrome 对比两次请求的 HTTP Cookie,找到了问题根源:一个名为 dc 的 session cookie(dc=st)——首次登录时该 cookie 尚未写入,服务端因此返回 302 跳转到登录页。解决办法是把它手动改成一年后过期的永久 cookie,整个诊断过程不到一小时。
如何定义 2026 年的 App 图标? (What’s an Icon in 2026?)
Apple 在 WWDC 2025 上推荐用 Icon Composer 制作图标,理由是让图标从静态图像走向“更具表现力”的多层作品——图标由此不再有唯一确定的样子,只有在具体设备、具体设置下被“观测”时才会呈现出某一种形态。以 Apple 电话 App 图标为例:绿底白话筒的经典形象,如今要分裂成深色模式、玻璃模式、多种着色的好几个版本。
Jim Nielsen 认为图标的价值本就建立在“简单、一致、易记”之上,越往“富有表现力”的方向堆叠变体,越是在稀释图标本该承担的即时辨识功能。
工具
ImmersiveMap:用 SwiftUI 与 Metal 构建原生沉浸式地图
ImmersiveMap 是 Artem Bobkin 开发的一款面向 Apple 平台的原生地图渲染引擎,用 Swift 与 Metal 实现,并通过 ImmersiveMapView 提供符合 SwiftUI 使用习惯的声明式接口。
项目最耀眼的能力,是球形地球与平面地图之间的连续过渡。此外,它还涵盖矢量瓦片(Vector Tile Source)解析、标签布局、3D 建筑、星空与昼夜效果、地图样式、相机飞行动画,以及支持聚合与动态移动的实时标记。开发者既可以直接使用内置瓦片运行,也可以接入 Mapbox 或自定义的 MVT(Mapbox Vector Tile)数据源。
ImmersiveMap 完整展示了如何把复杂的 Metal 渲染系统封装在简洁的 SwiftUI API 之下。对于想理解地图引擎、SwiftUI 与底层图形渲染如何协同工作的开发者来说,这是一份颇具参考价值的开源项目。