# 82 - 苹果为傲慢付出了代价

发表于

Article Image

Photo by Wesley Tingey on Unsplash

几天前,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 新特性速览 (What’s New in Swift 6.1?)

在之前的周报中,我已经推荐过多篇介绍 Swift 6.1 新特性的优秀文章。但当我读到 Paul Hudson 的这篇总结时,仍然发现了一些此前没有注意到的细节。其中,Metatype Keypaths 就是我当前项目中急需的能力,它使得我们可以使用 key path 访问类型的静态属性,不再受限于实例成员。此外,我最近在测试中使用的 #expect(throws:) 特性,也是在阅读本文后才意识到是 Swift 6.1 的新增功能。它的 API 调整让错误判断逻辑更加直观,减少了嵌套闭包的复杂度。

用 Mutex 保护可变状态 (Protecting Mutable State with Mutex in Swift)

actor 是保护共享可变状态的首选方案之一,但并不总是最佳选择,特别是当你不希望引入异步代码时。Swift 6 中新增的 Mutex 类型,提供了一种更符合现代并发模型的同步锁工具。Donny Wals 在本文中详尽介绍了 Mutex 的使用方式,并指出在某些情况下,Mutex 可能是更合适、更轻量的选择:

  • Mutex 是阻塞式的,适合用于快速、同步的状态访问;
  • 使用 Mutex 不会强制引入异步调用,因此不会干扰调用栈结构;
  • Mutex 本身符合 Sendable,可以很好地融入 Swift 6 的并发模型。

实现后台下载 (Keep Downloading with a Background Session)

从 iOS 7 开始,开发者便可以通过 URLSessionbackground 类型 session 实现断点续传与下载任务恢复。即使到了 Swift 6,Apple 仍未提供基于 async/await 的封装。在本文中,William Boles 详细介绍了 background session 的使用方式,并清楚解释了为什么这类任务不能直接支持 async/await。简单来说,background session 使用系统守护进程(nsurlsessiond)在 app 被挂起或终止后继续处理任务,而 async/await 则依赖于进程内的调用栈与任务树。两者运行机制不同,天然不兼容。

基于 Task Local 构建依赖容器 (Dependency Container on Top of Task Local Values in Swift)

Swift 的 @TaskLocal 属性为当前 Task 及其子任务提供了一种隐式的上下文传递机制。虽然这一特性使用频率不高,但在异步环境中,它是一种优雅的状态注入方式。Majid Jabrayilov 在本文中展示了如何基于 Task Local 构建一个依赖注入容器,适用于需要良好依赖隔离、又不希望依赖全局单例的场景。

值得一提的是,Swift 6.1 引入的 Test Scoping Traits 也是基于 @TaskLocal 实现的,它们在测试场景中可以很好地配合使用,构建出清晰可控的异步上下文环境。

深度链接实践全解 (Deep or Not Too Deep)

深度链接(Deep Linking)是提升用户体验、实现跳转归因与上下文还原的关键机制。随着移动系统的发展,Deep Linking 的实现方式也在不断演进。kyryl horbushko 在这篇内容详实的长文中,系统回顾了 iOS 与 Android 平台上深度链接的演进历史与原生实现方式,并深入讲解了如何借助 AppsFlyer 实现 deferred deep link 与归因跟踪。这是一篇值得收藏的参考资料。

🪜 用 Metal + SwiftUI 构建波动发光按钮 (Oscillating Glowing Strings with Metal and SwiftUI)

一如既往,Uladzislau Volchyk 再次带来一篇精彩的 SwiftUI + Metal 视觉实验。本文通过 colorEffect 与自定义 shader 打造出一个具有波动发光效果、可响应交互的按钮,并融合了 spatialWrap、haptic feedback 等 SwiftUI 技巧,为视觉层次和交互体验增添了更多细节。

工具

Chord Provider

ChordPro 是一种用于编排歌词与和弦的文本标记格式,而 Nick Berendsen 开发的 Chord Provider,则是一个专为 macOS 打造的原生开源 ChordPro 文件编辑与阅读器。项目完全采用 Swift 6 与 SwiftUI 编写,无任何第三方依赖。对 macOS 程序员而言,Chord Provider 涵盖了 DocumentGroup 管理、CoreAudio 播放、SwiftUI 多种布局能力等诸多实践细节,是一个值得参考的典范项目;而对吉他爱好者来说,它则是一款简洁自然、专注体验的桌面伴侣。

NSAlchemy:扩展 SwiftUI 的 macOS 控件库

尽管 SwiftUI 近年来在 macOS 平台上不断扩展,但依旧缺少不少关键控件。为此,Joshua J. Root 开发了 NSAlchemy —— 一个将常用 AppKit 控件封装为 SwiftUI 组件的库。当前版本中已包含 HSliderVSliderCircularSliderLevelIndicatorPathControlComboBoxCheckboxAcceleratorButtonContinuousButtonSearchFieldSegmentedControl 等组件,适用于构建更完整、更具原生感的 macOS 应用。

VS2X: VSCode 主题转换器

相较于 Xcode,VSCode 拥有更丰富的主题生态,用户社区也更热衷于分享与自定义。为此,Wei Wang (onevcat) 推出了一款在线工具,可将喜爱的 VSCode 主题一键转换为 Xcode 可用的格式。项目完全由 AI 驱动生成,作者也 开源了全部代码。对于这种目标明确、功能聚焦的应用场景,大模型的确已经具备了令人惊喜的实用性。

每周精选 Swift 与 SwiftUI 精华!