Fatbobman's Swift Weekly #149
Who Is the Slower App Review Process Actually Stopping?
Slower App Store reviews have become something more and more developers can clearly feel. In the age of vibe coding, the cost of building and iterating on apps has dropped dramatically, so it is not hard to understand why the review system is under greater pressure. The problem is that longer review times seem to be little more than a system overwhelmed by a growing volume of submissions, without a corresponding increase in the barriers that keep scam apps out of the store.
Recently, Jeff Johnson came across a highly suspicious Safari extension in the Mac App Store: its screenshots appeared to be AI-generated, advertised a nonexistent “4.9 out of 5” rating, and some of its five-star reviews were even dated before the app itself was released. Looking further, he found that the developer behind the extension had 41 apps on the App Store and had accumulated at least 368 approved review submissions over the past year—nearly one per day on average. Meanwhile, well-known developer Marco Arment’s new app had already been sitting in the review queue for 12 days.
This creates a rather awkward situation. On one hand, suspicious and potentially fraudulent apps can make it through review and climb the charts. On the other, AI has made rapid development and frequent iteration easier than ever, sending large numbers of both legitimate and high-risk submissions through the same review system and consuming its limited resources.
An urgent question is becoming difficult to avoid: Should App Review continue to treat each submission in isolation?
Johnson suggests introducing something akin to a trust system, allowing developers with a long history of following the rules and maintaining a good review record to receive faster reviews, while directing more resources toward accounts that submit at unusually high volumes, publish apps in bulk, or exhibit other suspicious patterns. Critics worry that such a system could eventually turn into preferential treatment for well-known developers or those willing to pay, further raising the barrier to entry for newcomers to the App Store.
Now that AI has dramatically reduced the cost of producing apps, a review model that treats every submission as an isolated case is becoming increasingly difficult to sustain. I see nothing unreasonable about incorporating factors such as a developer’s history, submission frequency, similarities among their apps, and metadata anomalies into risk assessment. A strong track record should not mean exemption from review, but rather fewer repetitive, low-value checks; suspicious accounts should not be barred from submitting, but should receive greater scrutiny.
Perhaps what App Review truly needs is not simply greater efficiency, but a shift from reviewing individual submissions in isolation toward evaluating patterns of developer behavior.
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 ☕️
Original
ContentBuilder Explained: The Secret Behind SwiftUI’s Type-Checking Speedup
In the WWDC 2026 session on what’s new in SwiftUI, Apple engineers introduced a new SwiftUI feature: ContentBuilder. Judging by how you use it, it looks like nothing more than a ViewBuilder with a wider reach — APIs that previously accepted ViewBuilder, ToolbarContentBuilder, or CommandsBuilder separately can now share a single builder. Apple also claims the change delivers a significant improvement in type-checking performance. This article digs into what ContentBuilder actually is, and where that performance comes from.
Recent Recommendations
Headless Xcode: From Prompt to Simulator with MCP
Xcode 27 beta 5 introduces xcrun mcp-server, allowing Xcode’s MCP capabilities to be exposed to external coding agents as a background service without launching the Xcode UI. Artem Novichkov uses Claude Code to demonstrate a complete Headless Xcode workflow: creating an Xcode project, generating SwiftUI code, building the project and rendering previews, launching the Simulator, reading the accessibility hierarchy, performing interactions, and finally verifying app state through screenshots and OSLog. This means a complete development loop—from prompt to code, then execution and verification—is beginning to take shape without relying on the Xcode UI.
iOS 26: Data Detector
iOS 26 introduces the new DataDetector, providing a more modern, Swift-native alternative to the long-standing NSDataDetector. Anton Gubarenko walks through the new API with numerous examples: developers can obtain an AsyncSequence directly through StringProtocol.dataDetectorMatches, then use native Swift ranges and strongly typed semantic results to identify email addresses, phone numbers, dates, addresses, monetary amounts, measurements, flight numbers, shipment tracking numbers, and more. The new API not only feels more natural to use, but can also recognize a richer set of semantic objects.
Measuring Elapsed Time in Swift with ContinuousClock
Many developers still habitually use Date() to record start and end times, but Date isn’t the ideal tool for answering “how long did this operation take?” Kyle Browning explores the Clock system introduced in Swift 5.7 and explains two more reliable ways to measure time: ContinuousClock and SuspendingClock.
ContinuousClock increases monotonically and continues counting while the device is asleep, making it suitable for measuring real-world elapsed time. SuspendingClock, by contrast, pauses while the device is asleep, making it more appropriate for measuring actual execution time. Kyle offers a simple rule of thumb: if Date() in your code is being used to “measure time” rather than “record a point in time,” you should probably consider replacing it with ContinuousClock.
From XCUITest to Promo Video
Every change to an app’s interface can mean recreating App Store screenshots, promotional videos, and assets for different languages. Noam Efergan proposes an interesting solution: treat marketing assets as reproducible build artifacts. Using launch arguments and fixed test data, he makes the real app enter deterministic UI states on demand, then uses XCUITest to automatically capture screenshots across different locales before passing the results to Remotion to generate promotional videos. Rather than maintaining a separate mock UI for marketing, the entire workflow keeps the actual running SwiftUI interface as its source material. It also demonstrates another value of testability beyond testing: when an app can reliably and precisely reproduce a given state, the same capability can support debugging, demos, localization, and automated marketing content production.
Software Engineering fundamentals matter more than ever
As coding agents become capable of rapidly generating code, completing tests, and even independently implementing fairly complex features, “can it be built?” is gradually becoming one of the easier questions in software development. Joseph Heck argues that the genuinely difficult parts have not disappeared: designing clear boundaries and abstractions, making software debuggable, maintainable, and composable, and making sensible tradeoffs among competing constraints. AI can significantly reduce implementation costs, but it cannot replace the software engineering skills built on experience, judgment, and a long-term perspective. In a sense, as “writing code that works” becomes easier, software engineering fundamentals matter more than ever.
Why Soft Skills Matter More Than Technical Skills in the Age of AI
If the previous article discusses “how to build software well” in the age of AI, Mohammad Azam takes the question one step further: first, we need to decide “what should be built.” As AI continues to reduce the cost of implementation, understanding the business, clarifying requirements, asking the right questions, communicating and collaborating, and evaluating tradeoffs become even more important. AI can produce ten implementation approaches in seconds, but it doesn’t know why a particular business rule exists within a company, nor can it take responsibility for the final product on behalf of the developer. Technical skills have not lost their value—they remain the foundation for judging whether AI-generated results are sound. What may become scarcer in the future is not the ability to “write more code,” but the ability to understand the problem, make sound judgments, and ultimately solve the right problem.
Tool
GlyphKit: Precise Glyph Layout in SwiftUI with Vector Outlines
Displaying a character in SwiftUI is easy, but making a glyph precisely occupy a specified region is not. Text is designed primarily for text layout, where baselines, font metrics, and Dynamic Type can all influence the final result.
GlyphKit takes a different approach by treating glyphs as graphics: it extracts the vector outline (CGPath) of an individual character through Core Text and renders it with SwiftUI Canvas, providing more direct control over size and positioning. GlyphKit is not a replacement for Text. It is better suited to individual decorative glyphs, while complex graphemes, ligatures, and content that requires text accessibility should still be handled by a full text layout system.
Thanks for reading Fatbobman’s Swift Weekly! This post is public so feel free to share it.
越来越慢的 App Review,拦住了谁?
App Store 审核变慢,已经是越来越多开发者能够明显感受到的变化。在 Vibe Coding 时代,App 的开发和迭代成本大幅降低,审核压力随之增加并不难理解。但问题在于,更慢的审核似乎只是被不断增长的提交数量拖垮,却没有相应提高诈骗 App 进入商店的门槛。
最近,Jeff Johnson 在 Mac App Store 中发现了一款颇为可疑的 Safari 扩展:截图疑似 AI 生成,展示着并不存在的“4.9 分”评分,部分五星评论甚至早于 App 的上架时间。继续调查后,他发现该扩展的开发者在 App Store 中拥有 41 款 App,过去一年至少产生了 368 次获批的审核提交,平均几乎每天一次。而在同一时间,著名开发者 Marco Arment 的新 App 却已经在审核队列中等待了 12 天。
这形成了一种颇为尴尬的局面:一方面,可疑甚至涉嫌诈骗的 App 能够通过审核并在排行榜上高歌猛进;另一方面,AI 又让快速开发、频繁迭代变得前所未有地容易,大量正常提交与高风险提交共同涌入同一套审核机制,持续消耗有限的审核资源。
一个紧迫的问题摆在眼前:App Review 是否还应该孤立地对待每一次提交?
Johnson 建议引入类似信用体系的机制,让长期遵守规则、保持良好审核记录的开发者获得更快的审核,将更多资源投入高频、批量和存在异常行为的账号。反对者则担心,这最终可能演变成对知名开发者或付费开发者的优待,进一步抬高新人进入 App Store 的门槛。
在 AI 大幅降低 App 生产成本之后,仅仅把每一次 submission 当作彼此孤立的对象进行审核,这种模式已经越来越难以为继。将开发者历史、提交频率、App 之间的相似度、metadata 异常等纳入风险评估,我认为并无不妥。信用良好不意味着免审,而是减少重复、低价值的检查;异常账号也不是禁止提交,而是接受更深入的审查。
或许 App Review 真正需要升级的,不只是审核效率,而是从单点“审核”迈向“行为判断”。
如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 Buy Me a Coffee 支持我的创作。
原创
ContentBuilder 解析:SwiftUI 类型检查性能提升的秘密
在 WWDC 2026 的 SwiftUI 新功能 Session 中,苹果工程师介绍了 SwiftUI 的一个新特性——ContentBuilder。从使用方式看,它似乎只是一个覆盖范围更广的 ViewBuilder:过去分别接受 ViewBuilder、ToolbarContentBuilder、CommandsBuilder 的 API,如今可以共享同一个 builder。苹果同时宣称,这项调整能够显著改善类型检查性能。本文将解析 ContentBuilder 的本质,探索性能提升背后的奥妙。
近期推荐
无界面 Xcode:利用 MCP 建立 AI 辅助开发的全自动流程 (Headless Xcode: From Prompt to Simulator with MCP)
Xcode 27 beta 5 新增了 xcrun mcp-server,让 Xcode 的 MCP 能力可以在不启动 Xcode UI 的情况下,以后台服务的形式提供给外部 Coding Agent。Artem Novichkov 以 Claude Code 为例,完整展示了一条 Headless Xcode 工作流:从创建 Xcode 工程、生成 SwiftUI 代码、构建项目和渲染 Preview,到启动 Simulator、读取 accessibility hierarchy、执行交互,并最终结合截图与 OSLog 验证应用状态。这意味着,从 Prompt 到代码,再到运行和验证,一个不依赖 Xcode UI 的完整开发闭环已经初具雏形。
iOS 26: Data Detector
iOS 26 引入了全新的 DataDetector,为已经服役多年的 NSDataDetector 提供了一套更符合现代 Swift 风格的替代方案。Anton Gubarenko 通过大量示例介绍了新 API 的使用方式:开发者可以直接通过 StringProtocol.dataDetectorMatches 获得 AsyncSequence,并使用 Swift 原生 Range 和强类型的语义结果识别文本中的邮箱、电话号码、日期、地址、金额、度量值、航班号、物流单号等内容。新 API 不仅使用起来更加自然,能够识别的语义对象也更加丰富。
用 ContinuousClock 替代 Date() 测量持续时间 (Measuring Elapsed Time in Swift with ContinuousClock)
很多开发者仍习惯使用 Date() 记录开始和结束时间,但 Date 并不是回答“这段操作持续了多久”的理想工具。Kyle Browning 围绕 Swift 5.7 引入的 Clock 体系,介绍了两种更加可靠的时间测量方式:ContinuousClock 和 SuspendingClock。
ContinuousClock 单调递增,并包含设备休眠期间经过的时间,适合衡量真实世界中的 elapsed time;SuspendingClock 则会在设备休眠时暂停,更适合衡量实际运行时间。Kyle 给出了一个简单的建议:如果代码中的 Date() 是用来“计时”而不是“记录时间点”,通常就应该考虑换成 ContinuousClock。
用 XCUITest 自动生成 App 宣传视频 (From XCUITest to Promo Video)
每次修改 App 界面,都可能意味着 App Store 截图、宣传视频以及不同语言版本的素材需要重新制作。Noam Efergan 提出了一个很有意思的解决思路:将营销素材也视为可以重复生成的 build artifacts。他通过 launch arguments 和固定的测试数据,让真实 App 可以随时进入确定的 UI 状态,再使用 XCUITest 自动完成不同 locale 下的截图,并将结果交给 Remotion 生成宣传视频。整个流程并没有为了营销重新制作一套 mock UI,而是始终以实际运行的 SwiftUI 界面作为素材来源。这也展示了 testability 在测试之外的另一层价值:当应用能够稳定、准确地重现某个状态时,同一套能力也可以服务于调试、演示、本地化以及营销内容的自动化生产。
AI 时代,软件工程基本功比以往任何时候都更重要 (Software Engineering fundamentals matter more than ever)
当 Coding Agent 已经能够快速生成代码、完成测试,甚至独立实现相当复杂的功能后,“能不能做出来”正在逐渐成为软件开发中更容易解决的问题。Joseph Heck 认为,真正困难的部分依然没有消失:如何设计清晰的边界与抽象,如何让软件具备可调试性、可维护性和可组合性,以及如何在各种约束之间做出合理的取舍。AI 可以显著降低实现成本,却无法替代这些建立在经验、判断和长期视角之上的软件工程能力。某种意义上,当“写出能工作的代码”越来越容易,Software Engineering fundamentals 反而变得更加重要。
为什么说在 AI 时代,“定义问题”比“写出代码”更重要?(Why Soft Skills Matter More Than Technical Skills in the Age of AI)
如果上一篇讨论的是 AI 时代“怎样把软件做好”,Mohammad Azam 则把问题向前推进了一步:我们首先需要判断“应该做什么”。当 AI 不断降低代码实现的成本,理解业务、澄清需求、提出正确的问题、沟通协作以及评估取舍的重要性反而更加突出。AI 可以在几秒钟内给出十种实现方案,却不知道公司的某条业务规则为何存在,也无法替开发者承担最终交付的责任。技术能力并没有因此失去价值——它仍然是判断 AI 生成结果是否合理的基础;只是未来更加稀缺的,或许不再是“能够写出多少代码”,而是理解问题、做出判断,并最终解决正确问题的能力。
工具
GlyphKit:在 SwiftUI 中用矢量轮廓精准控制字形排版
在 SwiftUI 中显示一个字符很简单,但要让字形精确地占据指定区域,却并不容易。Text 的首要目标是文本排版,基线、字体度量以及 Dynamic Type 都可能参与最终布局。
GlyphKit 选择把字形当作图形处理:通过 Core Text 提取单个字符的矢量轮廓(CGPath),再使用 SwiftUI Canvas 绘制,从而获得更直接的尺寸与位置控制。GlyphKit 并非 Text 的替代品。它更适合单个、装饰性字形;复杂字素、连字及需要文字辅助功能的内容,仍应交给完整的文本排版系统。
求贤
[深圳 / 上海 / 北京] 抖音研发 - 客户端渲染引擎研发工程师(iOS / 跨端渲染)
团队介绍
团队介绍:抖音研发部门负责多款大型产品的研发,包括但不限于抖音、西瓜视频、汽水音乐。 加入我们,你将有机会参与亿级用户场景的开发与架构工作,使用前沿的技术助力业务一起不断成长。
岗位描述
- 负责客户端跨端渲染基础框架的功能迭代与性能优化,持续提升复杂界面的流畅度与稳定性;
- 参与声明式 UI 框架在 iOS 上的能力建设,包括核心渲染能力、系统特性适配与配套研发设施;
- 深入渲染链路开展性能分析与调优,定位并解决卡顿、掉帧、内存与启动等关键问题;
- 参与渲染性能监控体系建设,结合监控数据推动问题的自动化分析、归因与治理;
- 沉淀通用优化方案与技术体系,对外进行技术输出,提升公司客户端整体研发效率与技术影响力。
岗位要求
- 本科及以上学历,计算机及相关专业;
- 3年以上 iOS/Mac 客户端开发经验,熟悉 Apple SDK,熟练掌握 Swift/C++;
- 熟悉 SwiftUI/Compose 等声明式UI框架的渲染机制,或有跨端UI框架的开发、落地经验;
- 具备扎实的性能优化能力,熟练使用 Instruments、Time Profiler、Allocations、System Trace 等工具进行分析与调优;
- 具有良好的代码驾驭能力与技术设计能力,能独立完成模块设计与复杂问题攻坚;
- 良好的沟通协作能力与服务意识,责任心强、自驱力强、追求卓越。
联系方式
内推联系:邮箱 yexulei.swift@bytedance.com
联系时请备注「客户端渲染引擎 + 姓名 + 工作年限」