在 weekly.fatbobman.com[1]订阅本周报的电子邮件版本。访问我的博客 肘子的 Swift 记事本[2]查看更多的文章。加入 Discord[3]社区,与 2000+ 中文开发者深入交流 Swift、SwiftUI 开发体验。
几天前,Epic Games 与 Apple 案迎来了一项重要裁决。法官认定 Apple 故意违反了法院于 2021 年发布的反垄断永久禁令,表面上虽允许开发者使用第三方支付渠道,但却通过高额佣金、用户体验障碍以及警告页面等方式,实质上继续维护着原有的市场垄断地位。法院不仅批准了 Epic 提交的执行禁令动议,还罕见地将 Apple 的行为移交给美国司法部加州北区检察官,以调查其是否构成刑事藐视法庭。
苹果凭借 iPhone 和 App Store 建立起牢固的商业壁垒,曾经那家特立独行、以创新为骄傲的企业,如今却逐步转变成它自己也曾试图避免的科技巨头。随着公司体量与市场影响力的增加,苹果逐渐从追求创新转向对市场地位的保护和防御,这本身并不奇怪——当企业规模足够大时,保护自身市场优势的收益,往往比不断投入不确定的创新更具吸引力。
App Store 的分成比例合适与否,完全取决于其给软件开发者带来的实际价值和服务。对于小型尤其是独立开发者来说,尽管佣金比例不低,但 App Store 提供的全球支付渠道、可信任的分发平台,以及便捷的推广手段,使它们能够相对容易地实现稳定的收入。但对于那些具备自主宣传渠道和广泛用户基础的大型科技公司而言,仅因通过 App Store 分发就被抽取高昂比例的收入无疑难以接受,这也是近年来苹果不断遭遇开发者和监管机构挑战的核心问题。
可以预见,本次裁决无疑会进一步加快全球各地监管、立法机构的跟进步伐,苹果“轻松收取过路费”的时代或将一去不复返。
苹果一直未能彻底摆脱以硬件为主导的发展路径,缺乏足够强大的网络服务吸引力,难以为生态内的开发者提供令人信服的增值服务。对于大量专注于苹果生态的开发者来说,他们天然倾向于使用苹果第一方的 API 和服务。苹果完全有能力通过提供更高效稳定的云端服务、更丰富且易用的大模型 API,甚至竞争力更强的 AI 云计算服务,来进一步增强自身生态的吸引力,并以更加令开发者认可的方式获得收益。然而,苹果迄今尚未迈出这关键一步。
本次裁决对苹果而言,不仅仅是对其傲慢姿态的警醒,更深刻揭示了其长期以来在生态建设中缺乏同理心、居高临下的态度所带来的必然反噬。希望这一教训能真正促使苹果重新审视自身生态战略,摒弃防御心态,以更加主动、开放、包容的姿态面对开发者社区,充分发挥自身技术与服务优势,重塑开发者的信任与合作热情。唯有如此,App Store 才能重回正轨,成为一个开发者、用户与平台方均能实现长期共赢的繁荣生态。
欢迎 点赞、 转发
NavigationLink
是 SwiftUI 开发者非常喜欢使用的一个组件,它巧妙地结合了 Button
和导航跳转逻辑,大大简化了代码实现。但在某些场景下不恰当地使用它可能会导致严重的性能问题,使应用响应变得迟缓。本文将尝试分析这个问题的成因,并提供一个实用但略显神秘(无奈)的解决方案——使用 equatable()
修饰器来优化性能。
在之前的周报中,我已经推荐过多篇介绍 Swift 6.1 新特性的优秀文章。但当我读到 Paul Hudson[6]的这篇总结时,仍然发现了一些此前没有注意到的细节。其中,Metatype Keypaths[7]就是我当前项目中急需的能力,它使得我们可以使用 key path 访问类型的静态属性,不再受限于实例成员。此外,我最近在测试中使用的 `#expect(throws:)`[8]特性,也是在阅读本文后才意识到是 Swift 6.1 的新增功能。它的 API 调整让错误判断逻辑更加直观,减少了嵌套闭包的复杂度。
actor
是保护共享可变状态的首选方案之一,但并不总是最佳选择,特别是当你不希望引入异步代码时。Swift 6 中新增的 `Mutex`[10]类型,提供了一种更符合现代并发模型的同步锁工具。Donny Wals[11]在本文中详尽介绍了 Mutex 的使用方式,并指出在某些情况下,Mutex
可能是更合适、更轻量的选择:
Sendable
,可以很好地融入 Swift 6 的并发模型。从 iOS 7 开始,开发者便可以通过 URLSession
的 background
类型 session 实现断点续传与下载任务恢复。即使到了 Swift 6,Apple 仍未提供基于 async/await
的封装。在本文中,William Boles[13]详细介绍了 background session 的使用方式,并清楚解释了为什么这类任务不能直接支持 async/await
。简单来说,background session 使用系统守护进程(nsurlsessiond
)在 app 被挂起或终止后继续处理任务,而 async/await
则依赖于进程内的调用栈与任务树。两者运行机制不同,天然不兼容。
Swift 的 @TaskLocal
属性为当前 Task 及其子任务提供了一种隐式的上下文传递机制。虽然这一特性使用频率不高,但在异步环境中,它是一种优雅的状态注入方式。Majid Jabrayilov[15]在本文中展示了如何基于 Task Local 构建一个依赖注入容器,适用于需要良好依赖隔离、又不希望依赖全局单例的场景。
值得一提的是,Swift 6.1 引入的 Test Scoping Traits[16]也是基于
@TaskLocal
实现的,它们在测试场景中可以很好地配合使用,构建出清晰可控的异步上下文环境。
深度链接(Deep Linking)是提升用户体验、实现跳转归因与上下文还原的关键机制。随着移动系统的发展,Deep Linking 的实现方式也在不断演进。kyryl horbushko[18]在这篇内容详实的长文中,系统回顾了 iOS 与 Android 平台上深度链接的演进历史与原生实现方式,并深入讲解了如何借助 AppsFlyer 实现 deferred deep link 与归因跟踪。这是一篇值得收藏的参考资料。
一如既往,Uladzislau Volchyk[20]再次带来一篇精彩的 SwiftUI + Metal 视觉实验。本文通过 colorEffect
与自定义 shader 打造出一个具有波动发光效果、可响应交互的按钮,并融合了 spatialWrap
、haptic feedback 等 SwiftUI 技巧,为视觉层次和交互体验增添了更多细节。
ChordPro 是一种用于编排歌词与和弦的文本标记格式,而 Nick Berendsen[22]开发的 Chord Provider,则是一个专为 macOS 打造的原生开源 ChordPro 文件编辑与阅读器。项目完全采用 Swift 6 与 SwiftUI 编写,无任何第三方依赖。对 macOS 程序员而言,Chord Provider 涵盖了 DocumentGroup
管理、CoreAudio
播放、SwiftUI 多种布局能力等诸多实践细节,是一个值得参考的典范项目;而对吉他爱好者来说,它则是一款简洁自然、专注体验的桌面伴侣。
尽管 SwiftUI 近年来在 macOS 平台上不断扩展,但依旧缺少不少关键控件。为此,Joshua J. Root[24]开发了 NSAlchemy —— 一个将常用 AppKit 控件封装为 SwiftUI 组件的库。当前版本中已包含 HSlider
、VSlider
、CircularSlider
、LevelIndicator
、PathControl
、ComboBox
、Checkbox
、AcceleratorButton
、ContinuousButton
、SearchField
、SegmentedControl
等组件,适用于构建更完整、更具原生感的 macOS 应用。
相较于 Xcode,VSCode 拥有更丰富的主题生态,用户社区也更热衷于分享与自定义。为此,Wei Wang (onevcat)[26]推出了一款在线工具,可将喜爱的 VSCode 主题一键转换为 Xcode 可用的格式。项目完全由 AI 驱动生成,作者也 开源了全部代码[27]。对于这种目标明确、功能聚焦的应用场景,大模型的确已经具备了令人惊喜的实用性。
参考资料
[1]
weekly.fatbobman.com: https://weekly.fatbobman.com
[2]
肘子的 Swift 记事本: https://fatbobman.com
[3]
Discord: https://t.ly/gzxeh
[4]
使用 equatable() 避免 NavigationLink 预构建陷阱: https://fatbobman.com/zh/posts/using-equatable-to-avoid-the-navigationlink-pre-build-pitfall/?utm_source=fatbobman%20weekly%20issue%2082&utm_medium=web
[5]
Swift 6.1 新特性速览 (What's New in Swift 6.1?): https://l.fatbobman.com/w082-01
[6]
Paul Hudson: https://x.com/twostraws
[7]
Metatype Keypaths: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0438-metatype-keypath.md
[8]
#expect(throws:)
: https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0006-return-errors-from-expect-throws.md
[9]
用 Mutex 保护可变状态 (Protecting Mutable State with Mutex in Swift): https://l.fatbobman.com/w082-02
[10]
Mutex
: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0433-mutex.md
[11]
Donny Wals: https://x.com/donnywals
[12]
实现后台下载 (Keep Downloading with a Background Session): https://l.fatbobman.com/w082-03
[13]
William Boles: https://mastodon.social/@williamboles
[14]
基于 Task Local 构建依赖容器 (Dependency Container on Top of Task Local Values in Swift): https://l.fatbobman.com/w082-04
[15]
Majid Jabrayilov: https://x.com/mecid
[16]
Test Scoping Traits: https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0007-test-scoping-traits.md
[17]
深度链接实践全解 (Deep or Not Too Deep): https://l.fatbobman.com/w082-05
[18]
kyryl horbushko: https://www.linkedin.com/in/kyryl-horbushko-67936bb5/
[19]
🪜 用 Metal + SwiftUI 构建波动发光按钮 (Oscillating Glowing Strings with Metal and SwiftUI): https://l.fatbobman.com/w082-06
[20]
Uladzislau Volchyk: https://x.com/i_u_ko
[21]
Chord Provider: https://l.fatbobman.com/w082-07
[22]
Nick Berendsen: https://github.com/Desbeers
[23]
NSAlchemy:扩展 SwiftUI 的 macOS 控件库: https://l.fatbobman.com/w082-08
[24]
Joshua J. Root: https://x.com/JoshuaJRoot
[25]
VS2X: VSCode 主题转换器: https://l.fatbobman.com/w082-09
[26]
Wei Wang (onevcat): https://x.com/onevcat
[27]
开源了全部代码: https://github.com/onevcat/vs2x
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有