Fatbobman's Swift Weekly #151
Just a Few KeystrokesLast weekend, I attended an App Accelerator event hosted by Apple in Beijing. The event focused primarily on app development, operations, and business models in the age of AI. Most of the attendees were managers at tech companies or app developers. Throughout the event, enthusiasm for AI was high, with people exchanging their own perspectives on AI and sharing how they were putting it to use. I learned a great deal from those conversations. After the event, I had dinner with a friend who works in a traditional industry. He knew almost nothing about AI. As an emerging concept, it was something he wanted to understand, but he had never really seen what tangible benefits AI could bring to his business. During dinner, he received a phone call: a client needed a proposal revised immediately. It was the weekend, and even if he assigned the task right away, it would have been difficult to get it done within a short period of time. After hearing roughly what was needed, I realized that the task happened to fall squarely within AI’s comfort zone. So I pulled out my phone and had AI handle it for him. A few minutes later, the result was ready. He was impressed not only by how quickly AI completed the task, but also by the quality of the result. And at his company, there happened to be a team of five or six people whose work largely consisted of handling similar tasks. He immediately started asking me for more details and calculating how much headcount he could reduce, and how much money he could save, if the company adopted AI. The speed of that shift caught me somewhat off guard. I immediately brought up another possibility: if AI can accomplish existing work at a much lower cost, could those newly available capabilities also be used to pursue opportunities that had previously been too expensive to explore? Cutting costs is certainly one of AI’s most obvious benefits, but generating new revenue is just as much a field where AI can make a difference. On the way home, I kept thinking about those five or six people. Right now they are probably enjoying a quiet weekend, unaware that their jobs had just been repriced over the course of a single meal. And what prompted that repricing was a demo I ran a few minutes earlier. The next time I find myself in a similar situation, I will probably still pull out my phone and show someone what AI can do. But I think I should at least remember this: what takes just a few keystrokes on one side of the screen may mean something very different on the other. 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 ☕️ Recent RecommendationsWhy Swift is introducing a warning for weak captures within nested closuresWeak captures are an important memory management mechanism in Swift. Historically, if a weak capture is used only in the inner closure of a nested closure, the Swift compiler may implicitly insert a strong capture in the parent closure. Even though this behavior can lead to a retain cycle in certain situations, the compiler previously provided no warning. Starting with Swift 6.4, the compiler will issue a warning when it detects a mismatch between a weak capture in an inner closure and an implicit strong capture in the outer closure. John Sundell explains this change and offers several solutions: depending on the situation, explicitly declare the capture semantics in the parent closure; if both closures need to manage their lifetimes independently, declare the appropriate capture semantics for each one. This may be a small update to the Swift compiler, but it helps developers express ownership relationships between nested closures that could otherwise be easily overlooked. Running iOS Background Tasks Reliably
For background tasks, developers should not try to precisely schedule execution. Instead, the goal should be to make the most efficient and correct use of the opportunities the system chooses to provide. The Memory Remains: TipKit in a Shipping AppTipKit is easy to learn, but using it well in a real project is much harder. The real challenges are knowing when tips should not appear, avoiding disruptions to the user experience, and ensuring that the underlying logic remains testable and maintainable. Wesley Matlock shares lessons from using TipKit in a shipping app: The essence of TipKit lies not in its visual presentation, but in its internal logic. It helps developers declaratively describe the rules that determine when tips should appear, while leaving the actual presentation entirely customizable. We can think of TipKit as a rules engine that determines whether a tip should be displayed; how those rules are visualized is up to the developer. For more discussion from this perspective, see Mastering TipKit: Advanced. Building an accessible calendar chart with Swift ChartsMatthaus Woolard demonstrates how to build a calendar chart similar to GitHub Contributions using Swift Charts. The more interesting part of the article, however, is its approach to accessibility. Because the same weekday across different weeks shares a normalized x value, VoiceOver groups an entire column of data together instead of allowing users to navigate day by day. The author solves this by using Swift Charts Beyond the Basics, co-authored by Matthaus Woolard and Natalia Panferova, was officially released last week. For developers looking to create advanced data visualizations with Swift Charts, it is a rare and valuable advanced guide. Mac App Direct Distribution, DMG Signing & Notarization GuideCompared with publishing through the Mac App Store, distributing a macOS app directly requires developers to handle more of the release process themselves: Developer ID signing, DMG creation, notarization, stapling, and final Gatekeeper verification. A problem at any one of these stages can prevent users from installing the app successfully. Stewart Lynch walks through the complete release workflow, from creating an Xcode Archive and building the DMG to final signing, notarization, and verification. Consuming SKIE Flows in SwiftUIIn projects that use Kotlin Multiplatform (KMP) to share business logic while building native UIs with SwiftUI, making Kotlin APIs integrate naturally into the Swift ecosystem has always been an important challenge. SKIE (Swift Kotlin Interface Enhancer) was created to improve this interoperability experience. It can convert Kotlin Gustavo Fão Valvassori introduces a set of SwiftUI-specific APIs provided by SKIE: besides consuming data directly from an Sarunw’s How-to Series ReturnsSarunw’s blog has long been an excellent resource for developers looking for practical tips on Apple platform development. However, the blog stopped receiving updates at the end of 2023. Last week, Sarunw resumed writing and published several new articles in his How-to series within just one week. It’s great to see an excellent content creator return after nearly three years away. ToolJindoKit: Preview Dynamic Island presentations in your appWidgetKit’s Live Activity previews are primarily intended for development and debugging within Xcode. For apps that allow users to choose themes or customize displayed content, however, the system does not provide an equivalent way to preview those presentations directly inside the app. Developed by Kyle Ye, JindoKit brings WidgetKit-style Dynamic Island APIs into regular SwiftUI Views, allowing apps to directly preview expanded, compact, and minimal Dynamic Island presentations. Since its API closely mirrors WidgetKit’s structure, developers can organize content for each region in a similar way and reuse related views and data between the app’s configuration UI and its WidgetKit Extension. For more information, see the author’s introductory article: Preview Dynamic Island presentations in your app with JindoKit. Thanks for reading Fatbobman’s Swift Weekly! This post is public so feel free to share it. 举手之劳上个周末,我在北京参加了由苹果举办的 App 孵化器活动,本次的主题主要围绕 AI 时代的应用开发、运营和商业模式展开。与会者大多是 IT 公司的管理者和应用开发者,整个活动期间,大家对 AI 的热情都很高,也纷纷讨论各自对于 AI 的理解和应用技巧,我从中收获不少。 会议结束后,我和一位从事传统行业的朋友吃饭。他对 AI 基本一窍不通。作为一个新兴概念,他也想了解,但一直没有切实感受到 AI 究竟能给他的企业带来什么。就餐过程中,他接到一个电话,一个客户要求立刻调整方案。当时正值周末,即便马上把任务安排下去,也很难在短时间内完成。我在了解大致需求后,发现这恰好属于 AI 的舒适区,于是直接用手机让 AI 帮他处理。几分钟后,结果就出来了。 他不仅惊叹于 AI 完成任务的效率,也对结果的质量感到意外。而在他的公司里,恰好有一个由五六人组成的部门,大部分工作就是处理类似的任务。 于是,他马上开始向我询问更多细节,并计算如果引入 AI,可以缩减多少人力、降低多少成本。 这个转变之快让我有些诧异。我随即和他讨论了另一种可能:既然 AI 能以更低的成本完成过去的工作,那么是否也可以利用这些新增的能力去尝试以前因为成本过高而无法开展的业务?节流当然是 AI 最直观的价值,但开源同样是它可以施展的方向。 在参加活动期间,我也曾在私下交流中表达过对 AI 冲击就业的担忧,不过更多还是从长期趋势出发的一种思考。当这种“担忧”突然以如此具体的方式出现在眼前时,我还是感到了一些不适。一个对我而言只是举手之劳的演示,在另一个人的视角里,却可能迅速变成一道关于几个人是否还有必要继续留在岗位上的算术题。 返程途中,我想的一直是那五六个人。他们此刻大概正安稳地过着周末,却并不知道自己的岗位刚刚在一顿饭的时间里被重新估价。而促成这次估价的,是我几分钟前的一次演示。 下一次遇到类似的场合,我大概还是会打开手机演示给对方看。但我想,我至少应该记得:屏幕这一侧的举手之劳,在屏幕的另一侧,或许是另一番境地。 如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 Buy Me a Coffee 支持我的创作。 近期推荐Swift 嵌套闭包弱捕获警告 (Why Swift is introducing a warning for weak captures within nested closures)弱捕获是 Swift 中重要的内存管理机制。一直以来,如果只在嵌套闭包的内层进行弱捕获,Swift 编译器可能会在父闭包中隐式插入强捕获。即便这种行为在某些场景下可能导致 retain cycle,编译器此前也不会给出提醒。从 Swift 6.4 开始,当编译器发现内层闭包的弱捕获与外层闭包的隐式强捕获存在差异时,将给出警告。 John Sundell 介绍了这一变化,并给出了解决方案:根据具体场景,在父闭包中显式声明引用方式;如果两层闭包都需要独立控制生命周期,则可以分别声明各自的捕获方式。这或许只是 Swift 编译器的一项小更新,但它能够帮助开发者更明确地表达嵌套闭包之间原本很容易被忽略的 ownership 关系。 提升 iOS 后台任务可靠性指南 (Running iOS Background Tasks Reliably)
对于后台任务,开发者努力的方向不应该是尝试精确安排执行时间,而是在系统愿意提供执行机会时,尽可能高效、正确地利用它。 TipKit 在真实项目中的落地实践 (The Memory Remains: TipKit in a Shipping App)TipKit 学起来很容易,但想在实际项目中用好并不容易。真正的难点在于:什么时候不应该显示、如何避免干扰用户,以及怎样保证这套逻辑可测试、可维护。Wesley Matlock 在本文中分享了他在真实项目中的使用经验:
使用 Swift Charts 构建无障碍日历图表 (Building an accessible calendar chart with Swift Charts)Matthaus Woolard 分享了如何用 Swift Charts 实现类似 GitHub Contributions 的日历图表。不过,文章更精彩的部分在于对 accessibility 的处理。由于不同周的相同 weekday 共享经过归一化的 x 值,VoiceOver 会将整列数据组合起来,而无法逐日浏览。作者通过
Mac 应用独立分发与 DMG 签名公证指南 (Mac App Direct Distribution, DMG Signing & Notarization Guide)相比通过 Mac App Store 发布应用,直接分发 macOS App 需要开发者自己处理更多发布环节:Developer ID 签名、DMG 制作、notarization、staple 以及最终的 Gatekeeper 验证,任何一个步骤出现问题,都可能导致用户无法正常安装。Stewart Lynch 完整演示了一套从 Xcode Archive、制作 DMG,到最终签名、notarization 和验证的发布工作流。 在 SwiftUI 中优雅消费 SKIE Flow (Consuming SKIE Flows in SwiftUI)在采用 Kotlin Multiplatform(KMP)共享业务逻辑、使用 SwiftUI 构建原生 UI 的项目中,如何让 Kotlin API 更自然地融入 Swift 生态一直是一个重要问题。SKIE(Swift Kotlin Interface Enhancer)正是为改善这一互操作体验而生,它可以将 Kotlin Gustavo Fão Valvassori 介绍了 SKIE 针对 SwiftUI 提供的一组 API:除了直接在 Sarunw 的 How to 系列回归Sarunw 的博客一直是很多开发者获取 Apple 生态开发技巧的优秀资源。不过从 2023 年底开始,博客便停止了更新。上周,Sarunw 重新开始创作,并在一周内连续推出了数篇 How to 系列文章。很开心看到一位优秀内容创作者在沉寂近三年后重新回归。 工具JindoKit:在 App 内预览灵动岛界面WidgetKit 提供的 Live Activity 预览主要服务于 Xcode 中的开发与调试;对于允许用户选择主题、调整展示内容的应用,系统并未提供相应的 App 内预览方案。 由 Kyle Ye 开发的 JindoKit,将 WidgetKit 风格的 Dynamic Island API 带入普通 SwiftUI View,让 App 能够直接预览展开、紧凑和最小三种灵动岛形态。由于其 API 与 WidgetKit 的结构高度一致,开发者可以用相近的方式组织各个区域的内容,并在 App 配置界面与 WidgetKit Extension 之间复用相关视图和数据。更多信息请参阅作者的介绍文章:Preview Dynamic Island presentations in your app with JindoKit。 唯音输入法由 Shiki Suen 开发的唯音输入法,是一款面向 macOS 的开源中文输入法。近期推出的「狂拼模式」,提供了类似中文之星智能狂拼、搜狗拼音、紫光拼音和升阳拼音(SunPinyin)的免输声调打字体验,部分词语还支持更激进的不完全拼写。 尽管支持类似狂拼模式的开源拼音输入法并不少见,但大多只支持汉语拼音。唯音借助自研的「齐铁恨(Tekkon)」注拼引擎,实现了对至少五种普通话拼音方案的狂拼打字支持。 Welcome to my blog Fatbobman's Swift Blog( 肘子的Swift记事本 )
|
