本集简介
双语字幕
仅展示文本字幕,不包含中文音频;想边听边看,请使用 Bayt 播客 App。
欢迎收听 Swift Over Coffee 第四季第二集。我是 Mikayla Karan。
Welcome to season four, episode two of Swift Over Coffee. I'm Mikayla Karan.
我是 Paul Hudson。
And I'm Paul Hudson.
在这一集中,我们讨论了在应用程序中如何处理数据。不要使用一堆不必要的框架,否则你懂的,最后会像我一样,什么都发布不了。
In this episode, we discuss how we handle data in our apps. Don't use a bunch of frameworks that you don't have to use or else you, you know, end up like me and don't ever ship anything.
我们分享了你对 Swift 开发者面临的小问题的看法。
We share your views on paper cuts for Swift developers.
我不知道在播客中该怎么强调这个词,但百分之百赞同。另外
I don't know how to capitalize that on a podcast, but 100% that. Plus
走廊里挤满了四处走动的极客,他们讨论着 PHP、Python、Ruby,现在还有 Swift 2.0。
Corridors are packed with geeks walking around sharing PHP or Python or Ruby and and now Swift two.
好,我们打算怎么开始这期播客?我之前已经搞砸了一次。我们看看最后会不会把它剪掉。Paul,你最近怎么样?
Okay. How do we wanna start the podcast? I already screwed it up once. We'll see if that gets clipped at the end. How have you been doing, Paul?
就在昨天,确切地说是当我们录制这个节目的时候,我庆祝了 Hacking with Swift 十周年。十年前我注册了这个域名,然后坐下来开始写最初几篇教程,这让我感到非常震撼。整整十年的 Hacking with Swift,也是我整整十年的写作和面对镜头自言自语。这是一段疯狂的旅程,也非常有趣。我想我学到了很多东西。
I have just literally yesterday, like, as we record this thing, celebrated the tenth anniversary of Hacking with Swift. I made the domain ten years ago and sat down, started writing the very first tutorials, which bends my brain. Like, a decade of Hacking with Swift is a decade of me writing, talking to myself to a camera. It's it's been a it's been a wild ride, and it's been a lot of fun. And I think I've learned a lot.
你知道,我学到了如何以一种聪明、合理、有条理的方式分享信息。但有很多人给我发消息说,恭喜你坚持了十年,接下来还有下一个十年。我当时就想,哇,再来十年这样的?整整二十年的 Hacking with Swift。
You know, I've learned a lot about sharing information smartly and sensibly in an organized way. But I had a whole bunch of folks, you know, message me saying, you know, congrats again ten years. Here's the next ten years. I'm like, oh, another ten years of this? Like, two decades of hacking with Swift.
那听起来是很长的一段时间。
That sounds like a long time.
是的,对吧?
It is. Right?
Hacking with Swift 这个域名是自动续费的吗?有没有可能,趁着我们知道注册纪念日,赶紧把 Hacking with Swift 抢注下来?
Is Hacking with Swift is it like on an auto renew domain? Like, there's no way for somebody now that we know the anniversary to really snag Hacking with Swift real quick?
那个域名挺安全的。
It is quite safe, that one.
我之前也有一个即将过期的域名。那是为一个副业项目注册的,但我可能只完成了注册新项目这一步,我觉得项目就到此为止了。
I also had a domain that is about to expire. It was a side project that I made the domain for, and I think did file new project, and I think that's how far it got.
是啊。老实说,拿到域名就已经完成了半个战斗,对吧?
Yeah. Well, that honestly, getting the domain's half the battle. Right?
没错,这确实是第一步。
It's it's true. It's it's the first step, really.
那你打算放弃那个项目吗?你是真的要停止这个副业、这个梦想?
And so you're gonna can that one? You're actually gonna stop the side project, the dream?
不,那个项目可能还活着,因为目前还没有其他应用做同样的事情。除非有人告诉我他们已经做了。我觉得现在还没有可以收藏推文帖子的 App。不过现在可能需要转变一下方向,有人可能需要为 Blue Sky 做一个收藏书签的应用,因为 Blue Sky 最近发展得非常快。
No. That one, it might still be alive because there's still no app that does that. Like, unless somebody let me know. But I think there's no app for bookmarking thread posts. But now, it may have to spin around and somebody needs to make a bookmarking app for Blue Sky because Blue Sky has been popping off a lot recently.
它的发展速度确实非常惊人。据我所知,整个 Apple 的布道团队都加入了 Blue Sky。对于那些想分享 Swift 和 SwiftUI 内容的人来说,这突然之间变得非常重要。过去两周左右,我涨粉了大约 2000 人。Blue Sky 的增长非常显著。
It's growing extraordinarily faster. The entire, as far as I know, Apple evangelist team just joined Blue Sky. For folks who wanna post about Swift and SwiftUI, it's huge suddenly. I've gained something like 2,000 followers in the last two weeks or so. It's remarkable, the growth there.
所以,是的,各位,如果你还没加入 Blue Sky,那你可有点错过了。
So, yeah, folks, if you aren't Blue Sky, you're kinda missing out.
是的。如果你不知道该关注谁,那就关注我,我会分享一个链接,类似于入门推荐列表,里面列了一些值得关注的人。有人已经整理了一些专注于苹果 Swift 和 iOS 开发相关的开发者名单。话说回来,目前我在 Blue Sky 上的粉丝数已经超过了 Mastodon,而我的 Mastodon 粉丝增长其实已经挺快的了。不过,等等,Mastodon 存在了多久?大概两年了吧?
Yeah. And then if you don't know who to follow, follow me and I'll drop the link to, like, starter packs, which are basically, like, lists of people to follow. People have just made lists of Apple Swift iOS dev kinda people. But, yeah, I have more followers on Blue Sky than I do on Mastodon already, and my Mastodon grew pretty quickly, but also, like, that's existed for what? To, like, two years now?
Blue Sky 虽然才出现不久,但已经超过了 Mastodon,这真是令人惊讶。
Blue Sky is existing for a little bit, has already surpassed that, which is wild.
不管怎样,先去关注 Mikayla,然后去催促她更新她的各种副业项目。对了,Fruitful 这个项目现在怎么样了?
Well, just follow Mikayla anyway and then badger her at her many side projects. Right? How's how's Fruitful doing?
实际上它现在做得还不错,因为 Revenue Cat
It is actually doing well because Revenue Cat
是的,是的。继续说吧。
Yeah. Yeah. Go on.
别表现得那么惊讶。但这是最新的消息,所以才在这里说。哦,Revenue Cat 宣布他们正在举办一个 Revenue Cat 增长挑战赛,如果你在这个比赛中获胜,你可以获得 15,000 美元的广告费用支持。
Don't sound so surprised. But this is breaking news. That's why it's here. Oh. Is Revenue Cat announced they are having a Revenue Cat growth challenge, which allows you to if you win this competition, you'll get, like, $15,000 you can use for ad spend.
而且,你还能与 App Masters 的 Steve P. Young 一起合作,包括参加各种会议,了解如何推广你的应用、建立用户群等等。我觉得这听起来太棒了。但当我读到规则时,发现你必须已经完成你的应用才能申请参加。我当时心想,这确实合理。
But also, you get to work, like, with Steve P. Young from App Masters, like, in meetings and everything and get to see, like, how to grow your app and, like, build its user base and everything. So I was like, that sounds awesome. Then I read the rules and you have to have your app finished to apply to that. And I was like, you know, that makes sense.
所以我们能完成它吗?自从我看到那篇帖子之后,这三四天来我一直非常努力地开发,就是为了完成我的应用。我其实早就知道我需要做什么,因为过去几个月它一直停留在同样的状态。几乎所有功能都完成了。只是遇到了一个非常隐蔽又令人头疼的钥匙串问题。
So can we finish it? And I've been working very hard for the past three days, four days since I read that post, basically, to try to finish my app. I knew exactly what I had to do because it's been sitting in the same state for the past months. Everything is almost done. I had a key chain issue, which was insidious and awful to figure out.
花了十二个小时调试,最后只改了三行代码,还移动了一个 if 语句的位置。
It took twelve hours of debugging to change three lines of code and move an if statement.
不错。但现在它能运行了,对吧?
Nice. But it works now. Right?
我想,我需要确认一下。
I think. I need to check.
所以现在它已经进入应用审核了吗?
So it's gone to app review now?
我本来想周日做的,但我们现在在录制,它改到周二了。
I wanted to do that on Sunday, but we're recording now. It's on Tuesday.
哦,所以是我的错。是的。
Oh, so it's my fault. Yeah.
哦,我明白了。
Oh, I see.
我现在明白了。哦,我明白了。我明白了。
I see now. Oh, I see. I see.
我明白。但是,不。我明天可能会试着去做。这是我目前的想法。
I see. But, no. It's I'm gonna try to do it probably tomorrow. It's what I'm thinking.
所以基本上是靠承诺给钱才让它实现的,对吧?
So it took basically the the the promise of money to make it happen. Right?
是的。我的意思是,这确实是一个很好的动力。所以
Yeah. I mean, that's a it's a good motivator. So
那它到底什么时候会上线呢?
So when's it gonna be live by?
所以比赛是在周五截止,也就是感恩节的第二天。然后他们应该会在下周公布获奖者。那样的话他们有一周的时间来做决定。从技术上来说,除非有类似‘请留下你的应用链接’这样的问题,否则我会说还在等待结果。如果那时还没有完全通过审核,但希望速度能很快。
So the competition closes on Friday, the day right after Thanksgiving. And then they announce the winner, I think the next week. So then they have a week to decide. So it's like technically, unless there's a question like that says drop your app link, I'll just be like, it's pending. If it's like not fully approved by then, but like, hopefully, it's pretty speedy.
我之前提交了一个自由职业项目的评论,那次不到24小时就完成了。所以我有点期待
I submitted a review for like a freelance project and that one took like less than twenty four hours. So I'm kinda hoping
非常快。
It's very fast.
可能同一个审核员就是这样的风格。另外,我之前做过一个Vision OS应用,那是很久以前的事了。那个应用当天就通过了审核。或者说,准确来说,大概在12到8小时之间,或者8到12小时之间就通过了。
Same reviewer might be like that. But also, I had an app when I did the Vision OS app, you know, way back when. That one got accepted the same day. Or no. It got accepted within, like, twelve to eight or eight to twelve hours.
如今审核速度非常非常快,这挺好的。在我们继续之前简单说一下,我最近还获批了另外一件事。我现在正式成为爱尔兰公民了,这对我来说意义重大。因为英国脱欧之后,我失去了在欧盟自由迁徙、居住和工作的所有权利,我的子女以及未来的孙辈也是如此。由于我的母亲出生在爱尔兰岛上,而且是在北爱尔兰出生的,因此只要我提出申请,我就可以自动获得爱尔兰国籍。现在我有了爱尔兰护照和爱尔兰身份证。
It it is very, very fast these days, which is nice to see. And just briefly before we move on, I've also been, approved for something else recently. I am officially now Irish, which is a big thing for me because after Brexit happened, I lost all the rights to be able to move around the EU freely and live and work anywhere as did my children and any future grandchildren or whatever. And, because my mother was born on the island of Ireland, born in Northern Ireland, I'm also automatically granted Irish citizenship if I apply for it. So I now have an Irish passport and Irish ID card.
我可以再次自由地环游世界了,去欧洲时也不用再忍受那些讨厌的护照排队,这对我来说意义重大。
I can travel the world freely again and skip all those nasty passport queues when I go to Europe, which is a big thing for
我。恭喜你。
me. Congratulations.
谢谢。不管怎样,这次我们收到了大量开放投票的回复。那么我们开始吧。首先,我们这次新闻中要提到的是,今天我们在录制节目的时候临近感恩节了,所以现在市面上有很多很棒的黑色星期五优惠活动。
Thank you. Anyway, we've got a huge collection of of replies to open ballot this time. So let's get on with the show. So first up in our news this time, as we record, it is approaching Thanksgiving. So there's a whole bunch of great Black Friday deals out there right now.
我刚刚购买了Chris Vaselli的日语课程应用中的全套日语学习包。他为那些想学日语的人提供了非常棒的服务。顺便说一句,如果你也想开发其他语言学习应用,可以向Chris学习。他对完美的追求非常值得一看。顺便说一句,现在有很多很棒的黑色星期五优惠,对我来说尤其适合语言学习。
I just picked up the entire Japanese language pack collection from, Chris Vaselli's Nihongo lessons app. He does great, great work there for folks wanting to learn Japanese. And if you wanna make other language learning apps, by the way, please be inspired by Chris. His approach to perfection is is very, good to see. By the way, there's some great Black Friday deals out there, right, for learning languages for me.
此外,你还可以购买书籍、应用程序和各种独立产品。现在正是购物的好时机,对吧?
But also, you can get books, you can get apps and indie stuff galore. This is the time to shop. Right?
还有独立应用的促销活动。因为,比如说,有一个网站你可以找到很多不同的独立应用,并查看哪些应用现在正在为黑色星期五打折。我觉得你可以通过这个筛选,或者直接使用 Command + F 来查看所有内容。非常棒。你可以去浏览一下。
There's also indie app sales too. Because, like, there's one website you can find a bunch of different indie apps and see what's on sale right now for Black Friday. I think you can filter by that or just do, like, command f and look at everything. It's amazing. You can go through, do that.
如果你还没提交过,你也可以把自己的独立应用提交到这个网站上。
And if you haven't, you can also go ahead and submit your own indie app to this as well.
是的。目前有indieappsales.com这个网站。Michael Tsai 收集了来自整个 macOS 和 iOS 生态系统的大量黑色星期五优惠信息。Marius Landwehr 也在 GitHub 上整理了一个堪称传奇的销售链接合集,人们可以通过提交 Pull Request 来添加自己的应用。所以,你有三个不同的地方可以去查找正在打折的商品,而且每年都会有一些非常惊人的折扣。
Yeah. So there's indieappsales.com. Michael Tsai has a huge collection of Black Friday offers from across the entire macOS and iOS ecosystem. And Marius Landwehr has his sort of legendary collection of sale links as well on GitHub where folks can submit pull request to add their own in the apps there. So there's three different places you can go to to find things that are on sale, and there's some amazing discounts available as always every year.
我得说,我自己的书也在打折。黑色星期五期间全部半价,包括我的全集套餐,只需 250 美元就可以获得我写过的每一本书,这非常划算。现在 Telemetry、Tower、Kaleidoscope 等许多优秀的产品也都在促销。所以大家一定要去看看这些链接,这是一个省钱的好时机。
I should say, my own books are on sale. They're half price for Black Friday, including my everything bundle for $250 to get every book I've ever written, which is great. There's awesome, wonderful things out there from, Telemetry and Tower, Kaleidoscope, and more have sales happening right now. So please do check out the links, folks. This is a great time to save some money.
Telemetry Deck 最近还宣布与 RevenueCat 建立新的合作关系。你可以将两者整合使用。
Telemetry Deck also recently announced a new partnership with RevenueCat. You can integrate the two together.
哦,是的,我也看到了。你说得对。
Oh, yes. I saw that too. You're right.
这真是太酷了。我迫不及待想尝试一下,因为我刚刚在 Telemetry Deck 上做了一个小仪表盘,用来显示有人购买东西的时候的数据。但有时候它会和 SyncKit Connect 的数据匹配不上,所以我就不知道哪个是对的。现在你可以把它们都整合在一起了。
That is super cool. And I can't wait to try that because I just made my own little bullion on Telemetry Deck of when somebody purchases something. But then it, like, sometimes would match with Synapstar Connect, and so I was like, I don't know what's right. So now you can put them all together.
是的。
Yeah.
我们也会在下方提供这个链接。
We'll drop the link to that as well.
接下来,Holly Baller 在 Swift 论坛上发表了一篇精彩的新博客文章。她发起了一场关于提升 Swift 中数据竞争安全性的可操作性的深入讨论。这听起来可能有点小众,但它的意思是他们正在寻找方法,让 Swift 6 在并发方面的改进更容易被开发者采纳。我很喜欢这篇讨论的开头,他们提到 Swift 6 语言模式提供了一个正确性的基础,但在采用过程中有时会让人感到沮丧。
Moving on. There's been a fantastic new blog post from Holly Baller on the Swift forums, because they've they've posted a long discussion or start a a long discussion, I should say, about improving the approachability of data race safety in Swift. And that might sound really niche. What it means is they're looking at ways to make Swift six changes around concurrency much, much easier to adopt. And I love the way the discussion starts because they say the Swift six language mode provides a baseline of correctness, but sometimes can be frustrating to adopt.
哇,这是一个非常坦率的承认。我想我们一直都知道,Swift 6会同时带来许多变化。无论是在框架层面还是语言层面进行微调和调整,这些改变都需要时间来稳定和融入。但现在他们公开表示,我们明白这令人沮丧,我们想要做得更好。
And wow, that's a huge admission. Now we always knew, I think, that Swift six concurrently changes. We're gonna be an ongoing refinement whether they're tweaking things, adjusting things, the framework level, language level, it takes time to settle in and embed in all these changes. But they're now saying openly, we know it's frustrating. We want to do better.
是的。当我在开始开发Fruitful时也遇到了这个问题,因为我认为我应用中的所有问题根源都是并发导致的,所以我打开了并发功能想看看情况。结果在我的小项目里,就已经出现了18个警告。我当时就在想,如果有人的项目有成千上万行代码该怎么办?不过,让并发变得更容易上手并不是我们目前必须立即去做的事情,因为它默认并没有开启。
Yeah. It's I did that when I was starting to make Fruitful because I thought the root of all the issues were concurrency based in my app because I just turned it on to see. And out of my my tiny project, I already had, like, 18 warnings. And I was like, how do people do this if they have thousands and thousands of lines of code? But making it more approachable it's not something we yet have to do, like, immediately because it's not on by default.
但如果你决定启用并发功能,那么让它变得容易上手就变得非常重要,这样你才能知道从哪里开始着手。这是我们将来某个时候必须去做并且要持续维护的事情。
But if you do decide to turn it on, making it approachable so you can kind of figure out where to start is super important for something that we will have to do and maintain at some point in time.
没错。因此我很高兴看到苹果决定在Xcode 16中默认不启用Swift 6。我们默认处于Swift 5的语言模式,这意味着开发者可以逐个案例地进行准备。比如,这个应用、这个模块或者这个框架可以使用Swift 6,而其他的暂时还不需要。这非常棒。但在这份文档中,他们还提到了一些相当引人注目的内容。
Yeah. So I was very glad to see that Apple went down the approach of making Swift six not enabled by default in Xcode 16. So we're in Swift five language mode by default, which means folks can carry on preparing on a case by case basis. You know, this app, this module perhaps, this framework, that one can be Swift six, this one not so much just yet, which is great. But but in this document, they've said something quite remarkable.
他们提到,正在考虑允许整个模块默认选择加入单线程模式。这对于许多原本不需要多线程、多任务处理的普通iOS应用来说非常重要。这也带来了一种可能性:你的Xcode SwiftUI应用模板,也就是你新建项目时生成的文件,默认就是单线程的,直到你显式启用并发功能为止。我认为这将极大地帮助实现Swift经典的渐进式披露(progressive disclosure)理念,他们希望一点一点地逐步增加功能,而不是像现在这样一下子把你扔进深水区,到处都是错误提示,比如需要标注main actor、隔离某些代码等等。
They've said they are thinking about allowing a whole module to opt in to being single threaded by default. And that's really important for all sorts of regular iOS apps that are out there that don't need multithreading, multitasking, whatever existing in the first place. And it raises the possibility. There's a possibility of your Xcode SwiftUI app template, you know, your file and new project stuff being single threaded out of the box until you explicitly enable concurrency. And that, I think, just would do wonders for the classic swift approach of progressive disclosure, where they want to do a little bit and a little bit more, little bit more on a case by case basis as opposed to right now where it kind of throws you in the deep end saying, well, there's errors all over the place, main act of this, isolate that, whatever.
这会让人很快感到困惑。因此,这可能意味着我们现在将首先构建同步应用,而不是默认以异步为主。当你准备好的时候,如果某些部分需要异步处理,没问题,你可以选择加入。
It gets very confusing very quickly. So it might mean it might mean we are now building synchronous apps first rather than async first. And then when you're ready, we need something to be asynchronous. Fine. You opt in.
是的。让这个功能能够并发运行。否则它就无法正常工作。不过现在还处于早期阶段,对吧?
Yes. Make this thing work concurrently. Otherwise, it wouldn't do. Anyway, it's early days yet. Right?
这还需要大量的讨论,但目前已经在进行中了。所以请务必参与进来。
And it needs a lot of discussion, but it's happening right now. So please do join in.
没错。正如你所说,大家都可以参与进来。这些讨论已经在Swift论坛上展开,也出现在各种进化讨论区中,你可以参与其中。
Yeah. And that's the thing, like you said as well, it's join in. You this is on the Swift forums. It's on, like, all the evolution dogs. It's you can participate in this.
接下来,我们共同的朋友James Dempsey——他因在Dub Dub DC演出中为慈善事业筹集善款的breakpoints团队而广为人知——发布了一门名为Swift Virtuoso的新课程,专门针对Instruments工具。我会在节目备注中放上链接,不过Mikaela已经看过课程了,对吧Mikaela?
Moving on. Our mutual friend, James Dempsey, who's very well known for his breakpoints group where they raised of money for charity at Dub Dub Dc gigs, has released a new course aimed at instruments called swift virtuoso. I'll have the link in the show notes, but Mikaela's been through already. Haven't you, Mikaela?
是的。课程已经进行到一半了。我们还有三节课,这是一个直播课程。所以我们是通过 Zoom 进行的,James 基本上每周教我们两次课,这个第一期课程总共大约有八次课。所以别太较真这个数字。
Yes. It's about halfway through. So we have three more lessons, and it is a live course. So we are doing Zoom sessions, and James is, like, teaching us every week, twice a week, basically, for about eight sessions for this first cohort. So don't hold me to that.
他之后可能会稍作调整,但这门课绝对物超所值。我参与的一个自由项目中遇到了性能问题,他的课程内容全是关于应用性能和使用 Instruments 工具的。因为他在最开始讲的第一件事就是你对工具的理解方式以及你如何使用 Instruments。你要想一想,首先你得学会读取数据。当你运行 Instruments 的时候,你要明确你想从中获取什么信息。
He might change it a little bit later, but it's definitely a 100% worth it. We're having issue performance issues in one of the freelance projects that I work in. So his course is all about app performance and using instruments because the very first thing he talks about is, like, your mental model that you have and how you use instruments. If you think about it, actually, you first have to like read the data. Pick what do you actually wanna extrapolate when you run instruments.
但在这之后,你还得学会解读这些数据。所以如果你能获取到这些数据,那很好。但如果你看不懂,哦,好吧,嘿。
But then after that, you have to also read the data. So if you can get that data, that's great. But if you can't read it, oh, well, hey.
有一半时间我都找不到它,Mikaela。它就在里面某个地方。我知道它在某个地方,但我就是记不起具体在哪里,该点击哪个选项、打开哪个面板、调出哪个检查器。有时候它确实有点复杂,对吧?
I can't find it half the time, Mikaela. It's in there somewhere. I know it's in there somewhere, but I can't remember where or which thing to click and open up and pull out or which inspector. It's a bit, a bit elaborate sometimes. Right?
确实是这样。但这就是这门课所教的内容:如何真正地解读、阅读这些数据,然后弄清楚,好,现在我们已经看懂了数据,我们能做些什么来解决我们遇到的问题?这门课绝对物超所值。就在第一天,他向我们展示了一些东西,我们所有人都惊呼:天哪,太震撼了。
It really is. But that is what this course teaches, how you really interpret, read this data, and then figure out, okay, now that we've read it, what can we do to actually fix the issue that we're having? And it's 100% worth it. Within, like, the first day, he showed us something, and we were all just like, oh my gosh. Mind blown immediately.
这门课的价值在我们刚开始的三十分钟内就体现出来了。我们还学到了 Instruments 中各种不同的模板。所以当你真正使用它的时候,你可以选择你想使用的模板,了解它如何影响你从应用中获取的数据。
This course is worth it within, like, the first thirty minutes that we had. And we also learned all about the different templates that you have at Instruments too. So when you actually go to use it, you pick whatever, template that you wanna use and how that affects what you're actually getting out of the app when you use Instruments.
Instruments 是一个非常强大的工具,一个极其强大的工具,但它太强大了,有时候反而有点复杂得让人难以驾驭。我已经好几年没教过 Instruments 了,但我记得上一次我教它的时候是在意大利。那次我让学员们大开眼界。我们当时在讨论一些旧的 GCD 代码,你知道的,那些并发代码的老古董。
Instruments is it's such a power tool. It's such a powerful power tool, but it is so powerful it kind of buckles under its own weight a little bit. And I've I haven't taught instruments for some years, but I remember the last time I did it was in Italy, I think. I blew folks mind. We're talking about some old GCD codes, you know, old priests with concurrency code.
对吧?我当时说,这段代码尽管用了 Operation Queue 来尝试在多个核心上执行任务,但运行得非常慢。我们来看看 Instruments。Instruments 有一个 CPU 视图,我们可以清楚地看到所有核心都在满负荷地工作,做了大量任务。
Right? And I was like, this code is running very, very slowly despite using operation queue to try and do things across multiple cores. Let's look at instruments. An instrument has a CPU view. We can literally see all the cores maxing out, doing lots and lots of work.
哦,这挺有意思。为什么它做了这么多工作,但还是这么慢?我们来看看,我们放大一下,放大一点。
Like, oh, this is interesting. Why is it doing, you know, so much work and yet it's still slow? Well, let's watch this. We kind of zoom in. Zoom in.
放大,放大,再放大。最终当你放大到足够近的时候,你会发现问题所在:一个调用在做大量的工作,然后它把同样的工作跳转到另一个调用,再回到第一个调用,再到第三个调用,又回到第一个调用,第五个调用。它实际上从来没有在多个调用上同时做任何事情。
Zoom. Zoom. Zoom. And eventually, when you're close enough, you realize what's happening is, like, one call is doing lots of work, then it's jumping the same work to another call, then back to the first call, then the third call, then the first call, the fifth call. It's never actually doing anything on multiple calls at the same time.
这个应用看起来好像在并发或并行处理任务,但实际上并没有并行处理。工具的使用让整个过程变得有些不透明。因此,任何有助于揭开这些工具神秘面纱的方法,我们都非常非常欢迎。
The app looked like it was doing things concurrently or parallel, and it wasn't doing things in parallel. The instruments kinda made it a little bit opaque. And so anything to help lift that veil of instruments, we most most welcome indeed.
绝对值得,我们肯定会在他下次举办该活动时放上链接。
A 100% worth it, and we will definitely drop the link to that whenever he runs the next cohort for that.
在我们进入主题之前,朋友们,Bacayla 和我都是 Swift 社区会议的超级粉丝,我们非常希望继续提高大家对这些会议的认识,帮助更多人参加附近举办的活动,去交朋友、学习知识、拓展人脉,无论你出于什么目的想去。去参加会议的理由有很多。因此,如果你是一位会议组织者,我们很乐意定期在这里展示更多活动。请联系我们,可以联系 Mikayla 或者我,或者我们两个人。当你开始发售早鸟票,或者发布演讲者公告,或者任何类似的事情发生时,我们会尽力为你宣传。
And before we go to the theme, folks, both Bacayla and I are big big fans of, going to conferences in the Swift community, and we're really keen to keep on raising awareness of that, helping more folks get to events near them to make friends, to learn things, to network, whatever reason you wanna go there. And there are lots of reasons to go there. And so if you're a conference organizer, we'd love to feature more events here on a regular basis. Get in touch with us. Mikayla or me or both of us, when you have, you know, early bird tickets going on sale or when, speaker announcement happening or whatever it is, we'll do our best to feature you.
事实上,接下来几个月里会有很多这样的会议,首先就是一月在新加坡举行的 iOS Conf SG。届时会有来自 Netflix 的 Carolyn Knits,Pixel Pal 的 Christian Selig,还有 Donnie Wiles、Jane Chow、Daniel Steinberg 等知名人士。
And in fact, there are a whole bunch coming up in the next few months or so, starting with iOS Conf SG in Singapore. That's January. There are speakers like Carolyn Knits from Netflix, Christian Selig of Pixel Pal's fame. They've got Donnie Wiles. They've got Jane Chow, Daniel Steinberg, and more.
当然,它也吸引了来自东南亚各地的大量观众。来自泰国、印度、菲律宾等地的人们都会聚集在那里,分享知识。
And, of course, it's attracted a huge audience from around Southeast Asia. So folks from Thailand and India and The Philippines and more kinda congregate there in one place to share knowledge.
还有一个我之前没听说过的会议是 Fostem,这是一个开源会议。在谷歌搜索之后,我发现它其实非常大,规模惊人。我之前完全不知道,可以说是孤陋寡闻了。
There's also a new conference that I personally haven't heard of is Fostem, which is an open source conference. And after Googling it, it's actually gigantic. It's huge. I just I did not know. I just was unaware living under a rock.
这是一个非常大的会议,Swift 被安排在所谓的 Swift 会场。整整两天都是关于 Swift 的内容,而且他们设有多个分会场。我之前完全不了解这个会议,但它竟然有二十多个分会场,涵盖各种开源项目,这个会议将在二月于布鲁塞尔举行。
It is a giant conference and Swift is accepted into what's called the Swift Room. So it's a whole two days of Swift and they have multiple multiple tracks. So, like, I didn't know about this, but it's, like, 20 some plus tracks of all different open source projects, and that is happening in Brussels, February.
我以前参加过 Fosdem。在接触 Swift、iOS 和 Objective-C 之前,我曾全职从事开源工作,那是我的生活。我去过那里,气氛非常热烈。
So I've been to Fosdead before. Before Swift and iOS and Objective C, I was doing fully open source work. That was my life was open source. I've been there before. It's really intense.
会议是在一个大学校园里举行的,很多人挤在一个非常小的空间里。走廊里挤满了四处走动的极客,他们分享 PHP、Python、Ruby,现在还有 Swift。我记得我曾以记者身份去采访这个活动,我们公司把我们安排在布鲁塞尔一个非常高档昂贵的区域。哦,但他们每天只给我们大概十美元的伙食费之类的东西。
It's it's in a university campus, and there's a lot of people in a very small space. The corridors are packed with geeks walking around sharing PHP or Python or Ruby and and now Swift two. And I remember I was visiting there as a journalist covering the event, and our company put us in a really swanky, expensive part of Brussels. Oh. And they gave us like a $10 a day food budget or something like that.
在这里我们几乎什么都负担不起,不得不走很远的路,因为布鲁塞尔实在太贵了。但这是一个很棒的活动,我认为这是一个很好的机会,让大家认识到 Swift 作为一个开源项目,不仅可以在 Linux 上运行,还可以在 Windows 等其他平台上很好地运行。我认为这是苹果公司目前的一个重要方向。所以我很高兴看到他们在 Fosdem 的出现。
Like, well, we can afford literally nothing here. We have to walk a very long way because Brussels is quite expensive. But it's it's a it's a great event and and it's a great chance, I think, to raise that awareness of Swift as an open source project that's available on on Linux and other platforms like Windows doing great things there too. I think it's a big push for Apple right now. So I am very pleased to see them at Fosdem.
接下来,我们在二月有五月的会议,地点是丹麦哥本哈根。然后三月份Let's Version OS将重返上海。今年他们将同时扩展涵盖人工智能和iOS领域。这将会是一场超级盛会,我也会在会上发表演讲。
Moving on, we have May's conference in February. That's Copenhagen, Denmark. Then Let's Version OS is back in Shanghai in the March. They're expanding this year to cover AI and iOS at the same time. That's gonna be a super event, and I'm speaking there as well.
之后三月份还有我们的北极会议。他们已经公布了演讲者名单,比如NS Screencast的Ben Sherman,AudioKit的Aurelius Pochatska,Calm公司的Elena Kafkes,以及其他更多嘉宾。我想Makeda和我都会去参加。对吧?
And then we have Arctic Conference at the March. They've announced speakers like Ben Sherman from NS Screencast, Aurelius Pochatska from AudioKit, Elena Kafkes from Calm, and more. I think both Makeda and I will be there. Right?
是的,我肯定会去。滑雪、桑拿,听起来都很棒。
Yeah. I'm definitely gonna be there. Snowboarding, sauna, all sounds great.
另外,如果你
But also, if you
没注意到,这是我看到的第一件事。
weren't That was aware the first thing I saw.
如果你之前没注意到,现在正是观赏北极光的太阳活动高峰期。而他们在芬兰的会场位置非常靠北,因此如果我们运气好的话,有很大机会看到非常壮观的北极光表演。我想说的是,我正在回想上一次在斯堪的纳维亚半岛举办的活动是什么时候。我想可能是很久以前在赫尔辛基举办的Swift和Fika活动吧。这些年来我认识了很多来自斯堪的纳维亚半岛的Swift开发者,我希望他们也能从挪威、芬兰或丹麦等地赶来参加这次活动。
If you weren't aware, right now is the solar maximum for the Northern Lights. And so they're so far north in Finland that is a very, good chance of seeing quite a dazzling show from the Northern Lights if we're lucky. What I would say is I'm trying to think when the last Scandinavian event was. I think it might have been Swift and Fika, in Helsinki some time ago. I've met so many Scandinavian Swift developers over the years, and I hope they're gonna be there from, you know, Norway or Finland or Denmark or whatever.
一定要去参加这些活动,支持这些本地活动,否则它们就不会再回来。顺便说一句,Tor,如果你在听的话,你知道我说的是谁。
Get there. Attend these things. Support these local events to you folks. Otherwise, they won't come back. And by the way, Tor, if you're listening, you know who you are.
我绝对期待在那里见到你。
I absolutely expect to see you there.
本期的主题是我们如何在应用程序中处理数据?比如Swift Data、Core Data、JSON、Firebase,有太多选择了。Paul,比如说,你现在对于Assembler项目是怎么处理的呢?
The theme for this episode is how do we handle data in our apps? Swift Data, Core Data, JSON, Firebase. There's so many options. Paul, what do you do for, let's say, assembler right now?
我会采用Mikayla Karen的专属方法,或者说应该申请专利的方法,那就是随便买个域名,然后发几条推文宣传一下,然后就再也不发布任何东西。我就是这么做的。喜欢这种方法,它很管用,对吧?
I take the patented or should I say patented Mikayla Karen approach, which is buying a domain somewhere and then, tweeting about it a few times and then not shipping stuff. That's what I do. Love it. It works. Right?
太喜欢了。
Love it.
不过更认真地说,我采用的是Ranger的方法。这很有趣,因为很长时间以来,我学会了对自己说,我想在应用中保存一些数据,但怎么使用CoreData呢?这真的很奇怪,因为我会问自己:你真的需要CoreData吗?他们之所以想用CoreData,是因为感觉这样更专业、更正确。
More seriously though, I adopt the Ranger approaches. And it's interesting because for a long time and I've learned to sort of say to me, I want to save some data in my app. How the heck do I use CoreData? And it was really weird because I'd say things like, well, do you need CoreData? Like, they they wanted to use CoreData because it kind of felt pro that the right approach to things.
但实际上,他们真正需要的是Codable,对吧?只需要用Codable就可以了。任何比这更复杂的东西可能都不值得麻烦。如果你需要更精细的过滤或排序,Codable也可以做到。
But really, they wanted Codable. Right? Just just use Codable. Anything more than that probably wasn't worth the hassle. If you want fine filtering or sorting, Codable can do that too.
如果你需要关系型数据,或者想存储大量数据,或者希望同步到CloudKit,等等,那当然,这些功能用Codable是实现不了的。但对于简单的应用来说,很长一段时间里,使用Codable都是最好的选择,可以避免CoreData那些奇怪又复杂的特性,比如CoreData模型编辑器对盲人用户完全不可访问的问题。所以对于很多人来说,我建议使用Codable。不过现在Swift Data的出现改变了这一切,因为我认为对于简单应用来说,Swift Data现在要容易得多。
If you want relationships or you want to store lots of data or you want syncing to CloudKit, whatever, fine. That is not codable. But for simple apps, just using codable was by far the best choice for a long time and avoid all the weird sort of idiosyncrasies of CoreData, things things like how hard it was to use for blind users because the model editor was not accessible at all. So for a lot of folks, I was saying use Codable. That has changed now with Swift Data because I think for simple apps, Swift Data is much, much easier now.
如果你不需要什么高级功能,比如动态排序之类的功能,Swift Data是一个非常好的起点选择。
If you don't want anything fancy, you know, like dynamic sorting and stuff, it's a great choice to start with.
从一开始就要保持一切简单。不要使用一堆你根本不需要的框架,否则你最后就会像我一样,什么都做不完。
Definitely keep everything simple from the beginning. Don't use a bunch of frameworks that you don't have to use or else you, you know, end up like me and don't ever ship anything.
我想我们俩要么是老师,要么是反面教材。在这种情况下,我觉得Mikaela就是个反面例子。
I think both of us can be either teachers or lessons. In this case, Mikaela's a lesson, I think. With
Swift Data确实可以做到这一点。它使用起来容易得多,不管我们稍后会提到的那些问题。从一开始来说,如果你只是想保存一点数据,做一些基本的过滤,Swift Data完全可以满足你的需求,你不需要做任何特别复杂的事情就能让它运行起来,甚至可以与CloudKit同步。
Swift data, definitely, we can. It's so much easier to use no matter the grievances that we will talk about later. But from the very beginning, just if you wanna save a little bit of data, do some basic filtering. Swift Data has you covered with that, and you don't need to do anything super complicated to just get it working to sync between CloudKit with only that user.
说到CloudKit,千万不要低估了它本身的能力。我这里不是指SwiftData或CoreData的自动同步功能,而是指实际存在的CloudKit API,它可以手动创建对象、更新、查询等等。当然,它只适用于在线应用,也就是说,它没有离线缓存功能,但它的表现其实非常好。
Speaking of CloudKit, don't underestimate CloudKit by itself. I don't mean SwiftData or CoreData auto syncing stuff. I mean the actual CloudKit API that exists for creating objects, updating, querying, whatever manually. Now, of course, only works with online apps, where online only apps that is. There's no offline caching, but it's really good.
你会听到有人说,哦,我无法让我的CoreData或SweatData应用按需与CloudKit同步。那是不可能的,这不是它的工作方式。但如果你自己编写CloudKit查询,你就可以实现按需同步。现在发送这些数据。
And you'll hear folks saying things like, oh, I can't get my CoreData or SweatData app to synchronize with CloudKit on demand. You can't. That's not how it works. But if you write CloudKit queries, you can make it work on demand. Now send this data.
现在就可以查询这个东西了。在这一点上,你拥有所有的灵活性和强大的功能。它真的、真的非常有效。
Now query this thing now. At this point, you have all that flexibility and all that power. It works really, really well.
这是你可以直接做的一件事,就是把它做成一个只能在线使用的应用。完全不用担心多设备同步的问题,比如在线和离线功能。目前市面上的每一个社交媒体都需要联网才能使用。比如你在飞机上飞行时,除非连接上Wi-Fi,否则你无法浏览Blue Sky。所以,先做一个只能在线使用的应用,从那里开始,之后再处理同步问题。
And that's one thing you could just do is just make it an online only app. Don't even worry about the multi device syncing, like online, offline capabilities. Every social media out there, you have to have Internet for. You can't browse blue sky while you're, like, flying unless you're connected to Wi Fi. So it's like, just make an online only app, start there, and then handle all that sync issue stuff later.
没错。而且不要认为你最初的选择就是最终的选择。对吧?你可以从Swift Data开始,然后说,好,现在我想要公开分享我的数据,而这正是Swift Data的一个已知缺点。
Yeah. And also, don't think that your first choice is your last choice. Right? You can start with Swift Data and then say, okay. At this point here, I want to do something like share my data publicly, a known drawback in Swift Data.
没问题。你可能在那个时候会说,我要迁移到Core Data,因为这种功能在Core Data中是可行的。所以你可以灵活调整,不会永远被困在某一个方案上。这并不是你唯一的选择。
Fine. You might say at that point, I'm gonna migrate to core data where that kind of thing is possible. So you can move around. You aren't, like, stuck on one thing forever. That's your be all and end all choice.
你可以改变主意。
You can change your mind.
后端技术总是在变化的。所以,真的,不要担心,或者至少不要因为有太多选项而陷入选择困难。只要想清楚:你的应用需要做什么?你需要在设备之间共享数据吗?
Every back end is always changing. So, really, don't ever really worry or almost don't even get stuck in analysis paralysis on it of just having so many options and not being able to choose one. Just think, okay. What does your app do? Do you need to share data between devices?
这真的很重要吗?还是说这是以后才需要的功能?随便选一个就行。比如,随便掷个骰子,选一个,然后老老实实开始做。因为你可以随时更改,毕竟没有哪个数据方案是永恒不变的。
Is it actually essential to do that, or is that a later feature? Just pick pick one. Like, I don't know. Roll a dice, pick one, and honestly, just start and go from there because you can always change it. Like, no data is the same.
Core Data已经存在很久了。现在我们有了Swift Data。希望将来Swift Data会不断加入很多新功能,并且会持续演进。你不会一直使用同一个方案的。
Core Data has been around forever. Now we have Swift Data. Swift Data is gonna add, like, lots of features, hopefully someday, and, like, it's gonna change all the time. You're not gonna stay on one.
现在我们来认真想想,我相信你是Firebase的忠实粉丝,对吧?是的,和我相比,你可是个大粉丝。我从来不用这些东西,所以相比之下,你就是超级粉丝。
Now let's think carefully here because I believe you're a big fan of Firebase. Yes. Mean, like, compared to me. I never use a thing, so you're a massive fan compared to me.
我使用Firebase,是因为我喜欢它处理一切的方式。但我不太喜欢它有时候会让代码库变得有点臃肿,因为Firebase本身实在太大了,它包含了很多不同的功能模块。我做Hacktoberfest项目的时候用了Firebase,原因之一是我当时不确定是否可以在开源项目中使用CloudKit,以及是否可行,还有就是它必须绑定到我自己的Apple账户上。那又该如何与其他人共享呢?
I use Firebase as in I do like how it handles everything. I don't like how sometimes it adds a little too much bloat to the code base because it is so gigantic. Firebase has a bunch of umbrellas of a lot of different things. So my Hacktoberfest project that I did uses Firebase, one, I wasn't sure about using CloudKit with an open source project and if that was possible, but also how it had to add to my own Apple account. And then how does that share with other people?
还是有什么奇怪的地方?我当时就想,不如直接使用 Firebase 吧。它已经有自己的 SDK 了。当时我还给 Firebase 发了条推文,问他们这个是怎么运作的?
Or is something weird? So I was like, let's just use Firebase instead. It's already got its own SDK. And I tweeted at Firebase at the time. I was like, how does this work?
我能这么做吗?好的,很酷。于是我就把它加进去了。最棒的是,你自动获得了在线和离线的支持,因为他们的 SDK 已经帮你处理了数据同步。
Can I do this? Okay. Cool. Threw it in there. And it's so nice that you get online and offline support automatically because their SDK handles that syncing for you.
这样一来你就不用自己去处理这些了。
So then you don't have to do it.
大家看,有一句众所周知的说法是:你购买或授权的代码是一种工具,而你自己写的代码则是一种负债。所以在这种情况下,使用 Firebase,或者对我来说是 Swift Data,它们能自动处理所有这类在线和离线的同步工作,意味着你可以专注于真正重要的部分。因为说到底,你选择的具体数据方案,不管是 Codable,还是数据库,是 Firebase 还是别的什么,这些并不会让你的应用变得有趣,对吧?
Look, folks, it's a it's a well known saying that code you buy or license is a tool. Code you write is a liability. And so having Firebase in this case, or for me, Swift Data, do all this kind of offline online synchronization stuff whenever automatically means you can focus on the bits that actually matter. Because look, your exact choice of data, whether it's codable, whether it's with data, Firebase, whatever, is not what makes your app interesting. Right?
你真正的独特卖点并不是你如何保存数据。用户根本不在乎这些。甚至都不在乎你是怎么保存数据的。它甚至可以用泥板刻下来,用户只关心其他部分。真正重要的是你在这些基础之上的构建。
Your actual USP is not how you save your data. Users don't care. Blunted it is could not care how you save it. It could be written down on clay tablets all they care. What matters is the bits you build on top of that.
所以不要陷入这种纠结:也许这样,也许那样的。选一个方案,继续前进。如果你一年后想回头优化它,那也完全可以。
And so don't get stuck down and thinking about this, maybe that, maybe that. Pick something, move on, and then if you want to revisit in a year's time to refine it, go to town.
不过没关系,作为开发者,我们会在乎。如果你做了某些选择,我们会为你鼓掌,但有时候也可能会带来麻烦。
It's okay though. We as developers, we care. We will applaud you if you do something, but it's also it could mess up.
当我看到一些重要的应用使用 Swift Data 开发时,我仍然觉得这是很勇敢的决定,因为有些功能它确实不支持,让我很困扰。比如我们无法使用复合谓词(compound predicates)。还有 MVVM 的支持几乎不存在。我不是说我特别喜欢 Core Data,NSFetchResultsController 也不怎么好用。
I still think it's brave when I see significant apps developing with Swift Data because there's things it doesn't do that really wind me up. Things like we can't do compound predicates. You know, the MVVM support just does not exist. I'm not I don't mean to say that I'm a big fan of core data. NSFetchResultsController isn't pleasant.
对吧?但我也并不想把数据放在视图里,因为我想要做单元测试。你知道的,我是一个重视测试的人。当然,老问题比如到处都是可选值之类的问题,目前来说确实有点难搞。
Right? But I also don't want my data in my view because I wanna have unit tests. You know? I'm a a testing kind of person. And, of course, if the old problem is about, like, optional everywhere and such, it's it's difficult right now.
这就是为什么当我开始开发我的第一个应用(严格来说是我做的第二个应用,但也是最早期的应用之一)时,我直接用了 SQLite,把数据保存到 SQLite 里,就是简单地保存到设备上。我的第一个应用根本没有多设备同步功能,但那个应用现在还在 App Store 上架着呢。
And that's why when I started one my very first app, technically second app that I made, one of the very first ones, I just use SQLite and save data to SQLite, SQLite, save data to there, and save it on device. Like, there is no multi device syncing in my first app, and that's still on the App Store too.
所以,你是直接在应用中编写 SQLite 的?用了类似 select * from xxx 这样的语句?
So you you wrote SQLite directly in your app? Used the select star from whatever.
我使用了 Steven Sellas 开发的 SQLite.swift 库,它提供了一种类型安全的方式来写 SQL。因为当时我刚从一个每天都要写 SQL 的岗位转过来,所以我知道怎么用这些东西。于是我就想,好吧,我就用 SQLite 吧。而且我看到别人也这么用,我就想,我也想像他们一样。
I used the SQLite dot swift library from Steven Sellas, which gives you type safe way to write SQL because at the time, I I was transitioning from a role where I did do SQL, like, every single day. So I, like, knew how to do all of that. So then I was like, okay. I'll just do SQLite. Plus, I saw somebody else do it, and I was like, I wanna be like them too.
所以我就那么做了。
So I did that.
这个库现在还用吗?是不是已经过时了?
How old is that? Is that old?
你是说那个库吗?
Like an old library?
或者你是说它真的已经很老了?那是你最早的应用吗?
Or Is is that actually is it that old? That was your very first apps.
对,大概是 2019 年,就是 SwiftUI 发布的那一年。我记得那时候我正在学习 UI Kit,不想让自己更困惑,尤其是当时很多人用 SwiftUI 1.0 的时候都遇到了很多麻烦。所以我就想,好吧。
Yeah. It was, like, 2019. It was the year SwiftUI was released, I remember. But I didn't learn that at the time because I was learning UI kit and I didn't wanna confuse myself on top of a lot of people who are struggle bussing it through SwiftUI v one point o. And I was like, okay.
我不想被搞糊涂了,所以我坚持使用 UI Kit,因为这个应用本身也是用 UI Kit 写的。而且我当时选择了 SQLite,部分原因是看到别人用,我觉得听起来挺酷的。
Don't wanna get confused. I'll stick with UI kit because the app is still in UI kit. Stick with UI kit, and I use SQLite because literally parse partially was it because I saw somebody else use it, I'm like, that sounds cool.
我是 SQLite 的超级粉丝。它的开发团队非常小,但他们对自己所做的事非常专注、非常投入。我认为它是有史以来最广泛嵌入的软件之一。
I'm a massive fan of SQLite. The the team behind it are very, very small and very, very committed to what they do. And I think it's one of the most embedded piece software of all time.
我也这么认为。
I think so.
领域代码。从iOS最初发布的第一天起,它就在macOS和iOS中无处不在。它非常庞大。所以,坦率地说,使用它是非常有趣的。顺便说一句,App Store上也有很多相关应用。
Domain code. It's all over macOS and iOS since day one for iOS. It's absolutely huge. So anyway, interesting to use that, frankly. And I there's a bunch of App Store available, by the way.
你知道,Gwendel Rueh Rueh有GRDB,也是在做类似的事情,只是方式不同而已。
You know, Gwendel Rueh Rueh has a GRDB and similar doing the same kind of idea, just in different ways.
所以归根结底,我们想表达的是,你选择什么其实并不重要。在当时选择一个你认为最好的方案就行,知道你以后肯定会改掉它,所以没关系。
So really, it's what we're saying is it doesn't actually matter what you choose. Pick the best choice you can think of at the time and know that you're gonna change it later anyways, so it's okay and it doesn't matter.
所以,我们刚刚用了十分钟的时间基本上就是在说这取决于具体情况。现在我们进入开放投票环节。这一次,我们问了大家一个问题:你在使用Swift、SwiftUI、Swift Data以及其他Apple框架时遇到过哪些小麻烦?这个问题的灵感来自上一集中的一条新闻,Swift基金会项目宣布了一项解决小问题的倡议,旨在修复框架中一些微小的烦人之处,以改善整体体验。这些都是一些小小的纸割伤,一些小小的、细细的伤口,虽然不大,但会让你烦躁、浪费时间或者引发问题。
So that was ten minutes of us saying it depends, basically. And now on to our open ballot. And this time, we asked you all, what were your paper cuts with Swift, SwiftUI, Swift Data, and other Apple frameworks? And this was based on some news from the last episode where the Swift Foundation project announced a paper cut solving initiative, trying to fix small little annoyances in the framework to make things better. Little tiny paper cuts, little little tiny little gashes here and there that wind you up or annoy you or waste time or cause problems.
我们收到了大量的回复。我想我们会在这里尽可能快地展示其中大约三分之一的内容。我们会尽量覆盖尽可能多的问题。不过有些问题,在我看来,并不算纸割伤。比如有人说,干脆抛弃Xcode重新开始。
We had a huge number of replies. We're gonna feature maybe a third of them, I think, here as fast as we can. We'll get through as many as we can. Some weren't, in my opinion, paper cuts. Someone was saying, you know, just ditch Xcode and start again.
那就不算纸割伤了。总之,我们挑选了一些较小的、也有一些较大的问题。我们会讲很多。我自己也列了一份纸割伤清单,这些是我写代码时经常遇到的烦人问题。最后我发现,你们每个人提交的问题,我自己也都有对应的体验。
That's not really a paper cut. Anyway, we've picked out some some smaller, some bigger. We'll get through quite a few. I ended up drawing up my own list of paper cuts, things that, you know, really vex me as I write code. And I ended up basically with enough that everyone you submitted, I had one of my own as well.
所以接下来要讲的有很多内容。很多抱怨,做好准备吧。Tim和其他几个人提到了Swift并发。当然,这是其中最大的问题之一。
So there's a lot to get through. Lot complaining. Brace yourself. Tim and several others mentioned Swift Concurrency. Of course, one of the biggest ones here.
他们说,希望Swift 6中新增的并发功能能提供更清晰的警告和错误描述。有时候真的很难搞清楚编译器到底想告诉你什么。这也呼应了我们刚才提到的新闻。我们之前讨论过让整个并发特性更容易上手的新方法。情况会变好的,大家。
They said, better warning and error descriptions will be highly appreciated, especially with all the new concurrency stuff in Swift six. It's sometimes really hard to figure out what the compiler's trying to tell you. This goes back to our news. We talked about the new ways to make this whole concurrency thing more approachable. It's gonna get better, folks.
很多人尝试在Swift 5.1中转向并发编程。我只是出于好奇试了一下,结果发现非常非常困难。到了Swift 6情况有所改善,部分是因为框架的改进,部分是因为语言本身的改进。这一块发展得非常快。我知道这显然是Swift团队的重点改进方向之一。
A lot of people try to move over to concurrency in Swift 5.1. Just out of curiosity, I certainly tried, and it was very, very hard. And it got better in Swift six partly because the framework changes, partly because the language changes. It's evolving very quickly here. So I know this is very clearly a target for the Swift team.
情况会变好的,我迫不及待了,因为我同意现在确实有点难。
It's gonna get better and I I can't wait because I agree it's hard right now.
是的。就像我说的,我们有一期节目专门讲这个,我自己也尝试着用我那个小小的、功能有限的应用程序做了一下SwiftUI。我现在明白你们在说什么了。
Yes. Like I said, we have an episode on this and I have now attempted to do a little swift six with my own teeny little tiny fruitful app. I see what you're all talking about now.
你已经看到我们在线上大喊大叫了,现在你也开始有同感了吧。
You've seen us screaming online and now you're feeling yourself.
我当时就想,哦,我现在懂了。不过没关系。就像我们说的,苹果公司已经知道这个问题了。这就是我们之前提到的、节目备注里提到的那篇帖子的内容。他们正在努力为我们所有人改进。
I was like, oh, I get it now. It's okay though. It's like we said, it's Apple is knows about it. That's what that whole post was about that we mentioned earlier that's in the show notes. They are trying to make it better for us all.
他们确实在改进。那我也提一个小小的抱怨吧,为了回应你之前提出的每一个问题。我很希望SwiftUI的列表能支持分段索引标题。就是你经常在UITableView或UICollectionView右边看到的从A到Z的那些小标签,比如在联系人应用里。你可以通过点击和滑动快速浏览A、B、C或者其他任何字母。
They are. So my little annoyance here, I'll throw one in for everyone you provide so far. I would love to see section index titles for SwiftUI lists. That's those little a to zed bars you see on the right hand side of UI table views or UI collection views, like in the contact app, for example. So you can tap and swipe through a, b, c, whatever very, very quickly.
在SwiftUI里你做不到这一点。你就是做不到。而这是一个很常见的需求。你做不了,所以你只能回到UIKit,使用UITableView。我们继续吧。
You can't do that in SwiftUI. You just can't do it. And it's a common thing to wanna do. You can't do it, and so you gotta bounce off to UI kit and UI table view. Moving on.
约瑟夫·汉弗莱提到过,那个臭名昭著的“表达式编译时间过长”的错误。我觉得人们一定有一些常见的模式或错误,如果不确切知道问题出在哪里,他们就可以基于常见原因,通过简单的模式匹配写出更具体、更有帮助的错误提示。
Joseph Humphrey said, the infamous expressions taking too long to compile error. I feel like there must be a common set of patterns or mistakes that people make, and that without knowing for sure what the problem is, they could write some more specific helpful error messages with some simplish pattern matching based on common causes.
我完全同意。我最近调试的时候也遇到了这个问题,我当时就在想,怎么会这样?所以我用了Command+A,Command+/,把整个部分注释掉,然后我再逐个把代码取消注释,直到找出到底是哪一部分导致了问题。
Completely agree. I hit this one recently when I was doing some debugging, and I was like, how how did this happen? So I just do command a, command slash, just comment the whole thing out, and then I go back through and comment everything back in one by one until I figure out what was the thing that broke.
是的。这正是SwiftUI第一个版本时的做法。到了iOS 14的时候改善了很多,但之后又变差了。你现在跟我做的一样,只能靠注释代码来碰运气。
Yeah. That was the approach in the very first SwiftUI version. It got a lot better in iOS 14 and then went downhill again. And you're now doing the same thing as me. It's commenting code out, hoping for the best.
有人,我记得应该是弗兰克·科维尔,在几年前的iOS Dev UK大会上做过一个演讲。他说每当看到这个错误提示的时候,他就会问:你有没有试着把你的视图拆分成更小的部分?这确实没错,因为当你遇到这种错误时,你会非常抓狂。错误就藏在里面某个地方,可能只是一个很小的问题。比如你在某个结构体里重命名了一个属性,而这个属性正在文本视图中使用,Swift就是看不到它,它会搞混然后报错。
Someone, I think it was Frank Corville, gave a talk at iOS dev UK a few years ago, who said whenever he sees this error message, he's like, have you tried breaking up your face into smaller parts here? And it's absolutely true because it's rage inducing stuff to have this thing where there's an error somewhere in there and it's a tiny thing. Like you've renamed a property in a struct somewhere. It's being used in the text view, Swift just cannot see it. It gets confused and throws up errors.
看,幕后有很多复杂性,尤其是在结果构建器(result builder)这些方面。是非常非常复杂的。这个问题很难解决。不过,这次我的抱怨要简单得多。我把我的抱怨分成了多个不同的类别。
Look, behind the scenes, there's a lot of complexity behind all the result builder and stuff. A lot a lot a lot of complexity. That's a hard one to fix. However, my complaint this time around is much, much simpler. It's I I divide my complaints into multiple different set categories.
比如,有时候它像是一个缺失的功能,有时候它是一个危险的功能。这属于危险功能的类别之一。UI 文本检查器是一个旧的 UIKit API,可以检测字符串中的拼写错误。你可以说,这是个字符串。
Like, sometimes it's like a missing feature. Sometimes it's a dangerous feature. This is one of the dangerous feature categories. UI text checker is an old UIKit API that detects typos in strings. You could say, here's a string.
这里面有什么错误吗?它会告诉你,哦,这里、这里和这里都有拼写错误,诸如此类。对吧?这很棒。但它是为 Objective-C 构建的,与 Swift 字符串配合使用时表现非常糟糕。
What mistakes in this? And it'll say, oh, there's a typo here, here, and here, whatever. Right? Which is great. But it's built for Objective C, and it does not behave well with Swift strings.
你必须提供一个 NSRange,表示你要检查的字符串长度。如果你传入的是 Swift 字符串的长度,它一定会搞砸。每次都是如此。它完全无法理解表情符号之类的内容。你必须使用 Objective-C 中的 UTF-16 长度。
You have to provide an NS range of the length of your string to check. If you pass in the length of your Swift string, it will screw it up. Guaranteed every single time. It does not understand emoji and similar at all. You gotta use the UTF 16 length from Objective C instead.
所以现在 UI Kit/50y 的这个 API 是非常危险的,我讨厌这一点。我讨厌这种容易误入的危险路径,简直就像自己用机枪对着脚开火。
So it's API in UI kit slash 50 y right now that's actively dangerous and I hate that. I hate it when this dangerous path is easy to fall into and basically machine gun yourself in the foot.
在写代码的时候,做任何以字母 s 开头的操作还是感觉有点奇怪,因为这时候你就会意识到,哦。
It feels weird still doing anything that starts with an s when you're writing any kind of code because then that's when you know you're like, oh.
我选错单词了。
I've taken a wrong It's word
我到底跑到哪儿去了?
where did I end up?
应该在阿尔伯克基左转的。总之,Todd Thomas 提了三个需求:第一,更好的调试;第二,更好的调试;第三,更好的调试。
Should've turned left to Albuquerque. Anyway, Todd Thomas asked for three things. First, better debugging. Second, better debugging. And third, better debugging.
哇哦。这已经期待很久了,对吧?我是说,我记得 Swift 早期的时候,它根本无法工作。你执行 PO 某个变量。
Woah. It's been a long time coming. Right? I mean, I remember the early days of Swift, it didn't work at all. You do PO, some variable.
结果它会说:不,没有这个东西。就像,我明明能看到它,你怎么就看不到呢?当时的原因是:听着,Swift 的 ABI 还不稳定。
It'd be like, nope. There's nothing called that. Like, well, I could see it. Why can't you see it? And and the reason at the time was, listen, Swift's ABI is not stable.
它一直在变化,调试器根本跟不上。好了。Swift 现在已经稳定了一段时间了,请给我们一个能正常工作的调试工具吧。
It's changing all the time. The debugger can't keep up with that. Okay. Swift's been stable for some time now. Give us working debugging, please.
是的。我觉得也没什么好说的了,更好的调试功能当然会很棒。
Yeah. I don't think there's anything else to say. Better debugging would be great.
我特别喜欢这个,基本上是整个 GameplayKit 框架。这是一个非常棒的框架,可以用来构建一些有趣的东西,比如应用中的 AI、你可以对战的 AI 敌人等等都在 GameplayKit 中。还有像强大的随机数生成、分布控制等等功能。这真的是一个很棒的 API,但它并不 Swifty。它在 Swift 代码中用起来很糟糕,而且其实也没必要这样。
My winch this one, basically, the entire gameplay kit framework. It's it's a wonderful framework for building interesting things like AI in your apps, game enemies you can play against with AI is in gameplay kit. Things like great randomization numbers, shaping and so forth in GameplayKit. It's really a lovely API, but it's not Swifty. It's horrible in Swift code, and it doesn't need to be.
我不明白为什么它就这样被放弃了。更让人恼火的是,你们可能听说过一个叫 Killed by Google 的搞笑网站,他们列出了谷歌定期放弃的大量产品。比如,哦,看,又一个通讯应用;哦,看,它已经死了。这种事层出不穷。
And I don't understand why it's just abandoned. And the annoying thing here is you might be familiar folks with this comedy website called Killed by Google, where they list out the very, many things that Google kills on a regular basis. You know, oh, look, another messaging app. Oh, look, it's dead. Whatever.
这种事情一直在发生。苹果不会明着这么做。苹果的做法是,当某个东西不再维护时,他们就直接放弃,什么都不说。GameplayKit、SpriteKit、SceneKit 并没有被官方宣布死亡,苹果也没有正式放弃它们,但它们实际上已经被放弃了,因为没人再继续开发这些项目了。
Constantly happening. Apple don't do that. Apple effectively, when something dies, they just abandon it and say nothing at all. GameplayKit, SpriteKit, SceneKit, they're not officially dead. Apple haven't killed them, but they kinda have killed them because no one's working on these things.
我真心希望 GameplayKit 能够开源或者 Swift 化之类的。比如像高斯分布这样的功能,真的非常棒。
And I really wish Gameplay Kit was open sourced or Swiftified or something. Because things like the Gaussian distribution, it's so so nice.
它们已经倒下了,却无法再站起来。
They have fallen and can't get back up.
在 SwiftUI 的领域里,Chris Hefferman 曾说,SwiftUI 的预览功能在正常工作时非常棒,但有太多次我坐在那里等着预览生成,心里想的是:要是直接写个应用都比这快。
Over in SwiftUI territory, Chris Hefferman said, SwiftUI previews, they're excellent when they work, but the amount of times I've sat waiting for a preview to generate and thinking to myself, it would have been quicker to have built the app is far too high.
我完全同意。有一段时间我干脆注释掉了所有的预览代码,因为它们总是出问题。所有东西都像是坏掉了一样,根本无法正常运行。现在我稍微多用了一些预览功能,特别是有了预览宏之后,写预览的代码少多了,注释起来也方便很多。但我感觉你更像是先构建了应用,然后再运行预览。
Completely agree. I just commented out pre all previews for a hot minute because they were struggling. Everything was, like, breaking and they weren't working. I use them a little bit more now, I think, with the preview macro because it's, like, way less code as well to write a preview and comment it out and everything. But I felt like you build the application and then you run the preview.
通常这样反而能跑起来。不过,是的,预览中传递数据的功能偶尔还是会有点问题。
That usually kinda works. But, yeah, it's the passing data through previews kinda still struggles a little here and there.
因此,苹果在 Xcode 16 中做了一个更改,在调试级别上,将你所有的 50 个 Y 视图类型擦除为 AnyView,以尝试让预览更好地工作。这可能起作用了,Chris。它或许比 Xcode 15 中的表现更好。不过我倾向于关闭它们,并不是因为我不喜欢它们。我是喜欢它们的。
So Apple made a change in Xcode 16 to at debug level, type erase all your 50 y views to be any view to try and make previews work better. It might have worked, Chris. It's perhaps better than it was in Xcode 15. I tend to turn them off, not because I I don't like them. I do like them.
但当我进行录制或直播等操作时,我需要更多的屏幕空间来让文字和代码在屏幕上清晰可见。所以我倾向于不使用它们。
But when I'm recording or streaming whatever, I kinda need the screen real estate to have my text and code nice and clearly visible on the screen. So I tend not to use them.
当你只是在编写一个视图本身,而不是像 UI Kit 那样编写一个完整的视图控制器,比如一个执行许多不同任务的完整界面时,你也可以使用它们。你可以只为某个特定的子视图或子组件使用 SwiftUI 预览,这样你就不用到处传递数据,因此它运行起来会稍微好一些。
You can also use them when you're just writing a view itself and not something that's like UI kit, like a whole view controller where you're writing an entire screen that's doing a bunch of different things. You can just use a SwiftUI previews for, like, styling one specific, like, subview, subcomponent, and then it's not like you're passing data everywhere, so it kinda then works a little bit better.
是的。对于调整和随意尝试、实验来说,它的反馈速度非常快。只是偶尔我会发现某些在预览中表现与模拟器不同的行为。每当这个时候,我可能会浪费很多时间在想,为什么它不工作了?哦,等等。
Yeah. It's it's a very fast turnaround for tweaking things and noodling around and experimenting. I I just occasionally occasionally I find something that behaves differently in previews than simulator. And when that happens, I can waste a lot of time saying, why is it not working? Oh, wait.
是预览的问题。这次,我的小烦恼是苹果的一些常用类型没有遵循 Equatable 或 Codable 协议。例如 CLLocationCoordinate2D,它就是两个 double 值。它是否是 Equatable 的?
It's the previews. For this one, my little annoyance is common types from Apple not being equatable or codable. For example, CLLocationCoordinate2D. It's a pair of doubles. Is it equatable?
不是。它是否是 Codable 的?也不是。你懂我的意思吧,想要保存这个位置的时候,却发现它不支持 Codable。而在 Swift 6 中,如果你尝试让这个类型遵循 Codable,你会收到一个警告,说你正在修改不属于你的类型的协议。
No. Is it codable? No. You you what I'm gonna say, save this location somewhere and it's not codable. And in Swift six, if you try and make this type conformed to codable, you get a warning saying you're changing a type that's not yours to protocol that's not yours.
这很危险,我明白。添加这种逆向适配的协议很烦人。苹果,请为我们加上这些协议支持吧。
This is dangerous. I get that. Add the retroactive conformance. Very annoying. Apple, please add the conformance for us.
接下来,Nigel G 说,有些修饰符在某些平台上不起作用。那就让苹果直接忽略它们好了。没错,没错。这是一个真正的痛点。
Next up, Nigel g says, modifiers that don't work on certain platforms. Just get Apple to ignore them. Yes. Yes. This is a real pain point.
比如 navigationSubtitle 在 macOS 上表现很好,但在 iPhone 上却不支持。那很好。在 iPhone 上就什么都不做好了。在其他平台能正常工作就行。有时候像 visionOS 的其他修饰符,在 iPhone 上也总是不起作用。
Things like navigation subtitle works great on macOS, but not on iPhone. Cool. Just do nothing on iPhone then. And it works elsewhere. Sometimes other modifiers like Provision OS, do nothing on iPhone whenever.
很好。那就让它成为标准吧。在所有平台上都给我提供这些修饰符,只是在不支持的平台上静默地不做任何事情。就像在其他平台上优雅地降级一样。
Great. Make that the standard. Give them to me everywhere. Just silently do nothing. Like, gracefully degrade other platforms.
很好。
Great.
就忽略它好了。这就是我们想要的全部。就像是,忽略我正在写的这段代码。
Just ignore it. That's that's all we want. It's like, just ignore the code that I'm writing.
看,显然不是所有情况都适用,因为那样会让人困惑,但确实有几个修饰符非常非常常见,每次都要根据不同的 macOS 版本去查一个小清单,真的很烦。一遍又一遍,真的很烦。
Look, obviously, not for everything because they get confusing, but there are a handful of modifiers that are very, very common, and it's annoying having to bounce them through some little hash if whatever macOS target. It gets annoying again and again and again.
那这一次你的 SwiftUI 抱怨是什么?
What is your SwiftUI grievance for this one?
有太多抱怨了。我就像一个充满怒火的小火球,Mikaela。我特别希望能在 SwiftUI 中通过照片选择器从相机导入照片。以前的 UI Kit 的视图控制器是可以做到的。你可以选择从相册或者实时调用相机。
So many grievances. I love I I'm like a sizzling ball of rage, Mikaela. I would love to import photos into SwiftUI using photos picker from the camera. There's the there's a way the old UI kit view controller worked. You could say from a photo library or from the camera live.
但 SwiftUI 做不到这一点。它只能从实际的相册中选取。如果也能直接调用相机那就太好了,因为现在这个功能非常难实现。接下来,Nicholas Degen 表示他希望在 SwiftUI 中看到更多系统标准组件,比如更好的导航栏自定义功能。
SwiftUI can't do that. It's only from the actual camera roll. It'd be great to say, actually, no, give me the camera here as well, because right now that is very hard to do. Next up, Nicholas Degen said they'd like to see more system standard components in SwiftUI such as better navbar customizability.
是的。这是一个很大的问题,你现在除了添加按钮之外,几乎无法对导航栏做任何自定义。比如说,我参与的一个自由项目中,我们在导航视图中使用了标题和副标题。在 UI Kit 中你可以添加自己的 UI 视图,但在 SwiftUI 中却做不到。
Yes. This is a big one that you still can't do anything, I think, to the navbar other than add buttons and, like, call it a day. But, like, one of the freelance projects I work on, we do, like, a title and a subtitle in the nav view. And you can add, like, your own UI view in UI kit, but, like, that's not a thing in SwiftUI.
没错。我觉得 SwiftUI 的问题是,把 API 设计正确是开发团队非常重视的事情。我的意思是,他们真的希望第一次就把 API 设计对。而在以前那种 UI Kit 的完全命令式方法中,我们可能只是设置一些布尔值为 true 或 false,或者在这儿放个字符串,那儿放个整数,添加 API 是很直接的。
No. I think the issue with SwiftUI is that getting the API right is something the team care about passionately. I mean, they really wanna get the API right first time. And in the old sort of UI kit, full on imperative approach, we'd say, you know, some boolean's true, some whatever's false, some string here, some integer there. It was fine to add API.
当然,Apple 仍然对这些 API 进行了大量审查。但添加 API 要容易得多。而 SwiftUI 不一样,要准确地设计出符合 SwiftUI 风格的 API 很难。像导航栏的自定义这种功能,其实也还好。
And it still went through API review galore Apple. Of course, did. But it was much easier to add API. Whereas in SwiftUI, getting the API exactly right in a way it feels like SwiftUI is hard. And things like nav bar customization, fine.
他们可以添加 20 个修饰符,比如字体、视图、样式、大小等等。但他们不想这么做。他们希望做出真正好用、原生感十足的功能。而要准确地把这些 API 的用词设计好,也就是你在 Xcode 中输入的那些代码,这才是难点所在,我觉得。
They could put in like 20 modifiers, the font, the view, the styling, the size, whatever. But they don't want to do that. They want to something that feels really good and really native. And getting that spelling right. The exact wording you type into Xcode is the challenge here, I feel.
拼写很难。
Spelling is difficult.
继续下一个话题。Joshua j Root 提到,如果有一个功能可以分析你的代码,并在你没有为控件添加标签时在编辑器中给出警告,那将是一件很棒的事情。这对于依赖这些标签的 VoiceOver 用户群体来说尤其重要。顺便说一下,Xcode 自带了可访问性检查器,它可以一目了然地告诉你这些标签是否设置得当。而且这个功能可以集成到你的测试中,你可以在进行 UI 测试时运行这些检查,确保所有控件的标签都设置正确,并提供反馈信息。
Moving on. Joshua j Root said, it'd be nice if there was some feature that analyze your code and provides an in editor warning if you don't give a control a label. This is obviously huge for things like the voice over community, who rely on these labels being there. And I should say, by the way, Xcode does ship with the accessibility inspector, which can tell you at a glance, yes, this stuff is good or not good, and can be built into your tests. You can run these tests at the UI testing time to say, check my layout for good labels everywhere and provide feedback from that.
写标签这件事我一直不太擅长,因为我总是不知道该写什么。另外,Dub Dub 还有一个关于如何编写可访问性标签和提示以及如何正确措辞的视频。所以我想建议大家,我们也可以放一个链接,大家可以去看看,学习一下怎么写这些标签,不要写像“添加按钮”这样的标签。
Writing labels is something I struggle with because I'm I never know what to write. There is also a Dub Dub video on writing accessibility labels and hints and how to phrase them properly. So I'd say, for everyone, we can drop a link as well. Give that a browse. Learn how to write them because don't write, like, button add button.
比如,不要把标签写成“按钮 添加”,因为 VoiceOver 默认已经会说出“按钮”这个词了。如果 Xcode 能够原生地告诉我们,嘿,这里应该加个标签,而不是只使用 SF Symbol,那会更好,因为 SF Symbol 在 VoiceOver 或其他发票控件中显示的是 SF Symbol 的名称,而其中一些名称真的很糟糕。
Like, don't make that the label because VoiceOver by default already says the word button. But having Xcode natively tell us, oh, yeah, add the label here rather than just use the SF Symbol because it shows up in VoiceOver and other invoice control as the SF Symbol name, which some of them are awful.
确实如此。继续下一个话题,MB 提出:在 SwiftUI 中,任何可以应用在视图上的修饰符,如果在应用后没有任何效果,编译器应该知道在这个作用域内存在某些与该修饰符配合工作的组件,并允许使用该修饰符,或者至少在你应用一个不会产生任何效果的修饰符时给出警告。
That's true. Moving on, MB said any modifier in SwiftUI that can be applied to a view but does nothing when applied. The compiler should know that something that works with some modifiers exists within that scope and permit it, or at the very least be able to warn you when you're applying a modifier, it'll have no effect.
这与 Nigel 刚才说的“忽略修饰符”正好相反。MB 的意思是,不要默默地忽略修饰符,而是应该告诉我们它正在忽略这个修饰符。我理解双方的观点。我更倾向于让编译器告诉我们修饰符被忽略了,这样你就知道为什么你试图让界面看起来正确的时候却没有任何变化,它会告诉你这个修饰符没有起作用,这就是你没有看到预期效果的原因。
And this directly opposes what Nigel had said of just ignore modifiers. MB is like, no. Tell us that it's ignoring the modifier. I see both sides of this. I'm more on the side of, like, tell me it's being ignored because then you kind of know, like, if you're trying to make something look right and something's not happening, maybe it'll tell you this modifier is not doing anything and that's why you're not seeing what you're trying to see.
我认为他们是从不同的角度来看这个问题的。Nigel 的意思是,比如我们想在 50 UI 代码中使用一些 macOS 或 watchOS 的修饰符。但目前,如果你的项目中偶尔包含一些 macOS 的代码,就需要用大量的编译指令来标注,比如 #if os(macOS) 这样的条件判断,这非常不友好。至于 MB 提出的需求,我甚至不得不在 Twitter 上专门询问澄清,因为我一开始也没太明白他们的意思。
I think they're approaching it from different angles. What Nigel was saying was that there are a bunch of macOS modifiers or watchOS modifiers, for example, that we want to use not 50 UI code. But right now, making one project that happens to have a bit of macOS here and there sprinkled through requires a bunch of compiler directives saying hash if OS macOS or whatever. It's not very pleasant. What MB is asking for I had to actually ask for clarification on, Twitter about this because I wasn't quite sure what they meant.
他们希望的是,当你有一个文本视图,里面有一些文本内容,比如“Hello World”之类的,然后你应用了例如 imageScale 这样的修饰符,这时候编译器应该弹出一个警告或错误,告诉你:这个文本视图不支持 imageScale。问题在于,UIKit 中的很多东西是通过环境不断传递和构建起来的。在文本视图的使用场景中,他们举的例子是 imageScale 和 symbolRenderingMode 设置为 pattern 模式。对于纯文本来说,这显然没有意义。但是在 SwiftUI 的 Text 中,你可以嵌入图片。
What they want to happen is that when you have, say, a text view where there's some text inside, you know, some hello world, whatever, and you apply, for example, image scale modifier to that, it should flag up a warning or an error saying, no, this text view does not support image scale. The problem with that is that so many things inside of UI build up and build up and build up by flowing through the environment. In the case of text use particularly, the example they gave was image scale and also symbol rendering mode to have pattern mode. For plain text, of course, makes no sense. But SwiftUI's text, you let's you embed images inside there.
你可以有一段文本,一个字符串,在其中嵌入一个 SF Symbol 图片。这时候 imageScale 和 symbolRenderingMode 是作用于文本中的图片,而不是一个简单的纯文本字符串。因此,编译器需要能够判断:这段文本只是一个普通字符串,不能应用 imageScale 或 symbolRenderingMode。
You have text, some string, and inside there, literally an image SF Symbol inside the TextView. And so image scale and symbol rendering mode would apply to the image inside the text, not to a simple TextString. And so for the compiler to then reason about, okay, this text you hear, that is just a flat string. That cannot have image scale. That cannot have symbol rendering mode, whatever.
但如果这段文本是一个包含图片的解释性字符串,这就带来了另一个层次的编译器复杂性。于是你又回到原来的问题:哦,现在它无法在合理的时间内完成类型检查了,因为复杂度又更高了。
Versus, oh, that's an interpreted string with some image inside it. That's a whole other level of compiler complexity. And then you're back to, oh, it can't type check yourself in reasonable time because wow, it's complex even more now.
无法进行类型检查。这就是所有问题的根源。
Cannot type check. That's the root cause of everything.
好的。这里我来提一个真正困扰我的小问题。一个真正困扰我的小问题
Okay. Here is one genuine paper cut from me. Genuine paper cut
来自我。所以其他的都可以忽略。
from me. So disregard all others.
是的,所有其他的。想不想看到每个数字范围的闭区间变体?因为你可以做到每个从零到100,但你不能做到从零到100的每个数字。
Yeah. All others. Wanna see a closed range variant for four each. Because you can do four each zero up to a 100. You can't do four each zero through a 100.
零...到100是不允许的。我烦透了新手给我发邮件。我真的受够了有人发邮件跟我说,为什么这段代码不起作用?为什么这个东西能运行?那个却不能。
Zero dot dot dot a 100 is not allowed. And I'm sick of beginners emailing me. I'm so tired of folks emailing saying, why does this code not work? Why does this thing work? That doesn't work.
因为它只支持半开区间范围,这就是原因。大多数用户并不关心这些。他们只是想写“从1到100做这件事”,而不是,你知道的,从零到100或者从1到101之类的。所以这是一个非常非常小的烦恼,也许苹果这么做是有原因的,我也不清楚,但我真的厌倦了收到这些邮件。
Because it only supports half open range. That's why. Most users don't care. They just wanna say for one through a 100 do this thing as opposed to, you know, zero to a 100 whenever or one one zero one whenever. And so it's a tiny tiny annoyance, and maybe there's reasons for it, an Apple, I don't know, But I'm sick of getting the emails.
也许我会把这些邮件转发给SwiftUI团队,好让他们被这些问题烦到去解决它们。不管怎样,Dale Buckley 表示他们希望看到自定义的导航动画,或者更广泛地说,更好的导航选项。目前的导航选项对于小型应用来说没问题,但一旦你开发的是大型应用,包含多个功能模块,比如那些超过700万行代码、使用更复杂场景的应用时,现有的导航功能很快就不堪重负了。苹果在iOS 18中加入了缩放导航功能,这很棒。我很高兴看到它的推出。
Maybe I'll maybe I'll just forward my emails onto the SwiftUI team to annoy them into solving these problems. Anyway, Dale Buckley said they'd like to see custom navigation animations or actually just better navigation options in general. The current navigation options are fine for smaller apps, but as soon as you get to large apps with many feature modules, there are examples over 7,000,000 lines of code with more complex use cases, it breaks down quickly. Apple added the zoom navigation with iOS 18, which is very nice. I'm glad to see it.
我有点希望这是迈向添加完整过渡代理风格API的第一步。某种方式,将匹配几何效果结合在一起。这样,无论是从一个界面推到另一个界面,无论是sheet形式还是导航推送,你都可以完全自定义布局和过渡效果。
I am kind of hoping that's the first step towards adding a full on transitioning delegate style API. Somehow, some kind of matched geometry effect meets together there. So we push from a to b, whether it's a sheet or a navigation push or whatever, you can fully own that layout and transition however you want to.
是的。在UIKit中你可以实现的自定义导航过渡效果非常酷。但在SwiftUI中我们没有这样的功能。当然,一开始SwiftUI的导航功能还行,现在我们有了基于模型的导航方式,比如navigation destination、navigation stack和navigation path。但是一旦你开始处理一个大型项目,我个人还没有处理过像700万行代码这样的项目。
Yeah. The custom navigation transition stuff that you can do within UI kit is super cool. And we don't get that in SwiftUI. But also, yeah, it's when you all the navigation in SwiftUI was kinda okay at the very beginning, and then now we have it powered by models more with navigation destination, navigation stack, and navigation path. But, yeah, once you work on a project that large, which I personally have not worked on a project with, like, 7,000,000 lines of code.
但是一旦到了那个规模,我想像得出你想要展示各种内容时会有多复杂,各种不同的展示条件。在那种情况下,SwiftUI可能就开始有点撑不住了。
But But once you get to that point, I imagine how you wanna present different things with so many different conditions for presenting something. SwiftUI probably starts to break down a little bit there.
顺便说一下,我应该提到导航栈和导航目标 API 是我最喜欢的 UI 代码之一。我很喜欢它的运作方式。对我来说,只需要说一句,好的,这是我的路径,然后去寻找栈的路径,这非常自然。
I should say, by the way, that navigation stack and the Navigation Destination API is some of my favorites of UI code. I love the way it works. It's just so natural for me to have to say, okay. Here's my path. Find the path of the stack.
你可以随时向栈中添加内容。它实现得非常出色。不过,在 50y 的范围内,我还有另一个小小的不满,另一个小小的烦恼。同样,我认为这个问题很简单,希望它真的简单。
Add things to the stack whenever you want to. It's done really, really well. However, in 50 y territory, I have another little grievance here, another little paper cut. And again, I think it's simple. I hope it's simple.
天哪,我非常希望看到一个用于显示 CN 联系人的文本视图初始化方法重载。那是在联系人框架里。这样你就可以自然地显示人们的名字。实际上,现在已经有针对人名组件的初始化方法了。
Goodness me. I would love to see a text view initialize overload for displaying a CN contact. That's in the contacts framework. So you can display people's names naturally. There's actually one already there for person name components.
如果你手动创建了某人的名字组件,这里就可以用了。但如果你是从新的联系人 UI 中导入一个联系人,并用 SwiftUI 来处理,你肯定想说,嘿,正确地显示这个人的名字,这应该是自动完成的。而我现在看到的情况是,虽然这个 API 并不危险,但也不够好。结果,人们只能在代码中硬编码字符串插值来拼接名字,比如简单的名+姓。
If you make someone's name components manually, here you go. But if you import a contact from the new contacts UI, stuff with SwiftUI, you wanna say, hey, show this person's name correctly, that should be automatic. And what I see again right now, see this. It's not a dangerous API, but it's not a great API. As a result, people will just do first name, last name, like hard coded string interpolation in their code.
这并不理想。我真心希望正确的选择就是最简单的选择。这样,无论哪个地区、哪种名字,都能自动正确地格式化显示,而不是像很多人那样硬编码地使用名+姓的方式。说到让正确的选择变得简单,Hunter 提到他们想要一种现代的方式来使用钥匙串(keychain)。
It's not great. I really want the right choice to be the easy choice. So you get correct name formatting for every locale, every name automatically just out of the box, rather hard coding first name, last name like a lot of folks do. Now speaking of making the right choice the easy choice, Hunter said they want a modern way to use keychains.
完全同意。我不知道在播客里该怎么强调这一点,但确实是百分之百正确。这并不是一篇博客文章,而是我在 Fruitful 遇到的一个根本性 bug,就是因为我没有正确地将某些内容保存并读取自钥匙串。天哪,就是这个问题。
100%. Like, I don't know how to capitalize that on a podcast, but 100% that this is not a blog because this was the root of the bug that I just had at Fruitful was I was not saving something and reading it properly from Keychain. Oh my gosh. This one. This one.
好吧,我们在这里休息一会儿,让 Mikaela 在镜头外哭一会儿。
We'll have we'll have a little break here while Mikaela sobs off off camera for a little while.
请在三到五个工作日内不要联系我。
Please don't contact me for three to five business days.
你看,应用存储(app storage)运行得非常非常好,因为它总是能正常工作。读取一个字符串、写入一个字符串,无论读写什么都总是没问题。但从钥匙串中读取数据可能会以各种方式失败。因此,SwiftUI 团队必须找到一种方式来表达:是的,把这个写入钥匙串,但当我们无法写入时,我们也要能正确地处理错误。从 API 的角度来看,如何很好地表达这一点是具有挑战性的。
Look, app storage works very, very well because it it's always gonna work. You know, reading a string, writing a string, reading into writing into whatever, it's always gonna work. Reading from the key chain can fail in many and varied ways. And so the SwiftUI team have to find a way to say, yes, write this to the key chain, but then here's how we handle errors correctly when we can't write the keychain. And that is challenging from an API perspective, how to express that very, very well.
目前的问题就和 c nContact 一样。这是一个例子,说明最容易做的事情往往不是最好的做法。对于 c nContact 来说,最容易的做法是:如果你拿到了联系人数据,我就只是简单地用名+姓的方式硬编码顺序,这对世界上很多语言来说都不太好。而对于存储数据来说,最容易的做法是使用应用存储。这个应用存储中的用户名、密码等等,就直接摆在你面前,非常明显。
The problem right now is just like c nContact. It's an example of where the easiest thing is not the best thing to do. The easiest thing for c nContact to say, okay, if you got that, I'll just do first name, last name, hard code that order, which is not great for many languages around the world. The easy thing for storing data is app storage. This app storage username, password, whatever, it's right there screaming you in the face.
请不要那样做。在应用程序的 app storage/user defaults 中存储信息非常非常危险。钥匙串才是存储重要凭证的正确地方,但它的使用难度实在太高了。我是说,它用起来让人困惑地困难,而且很容易出错。好吧。
Please don't do that. It's so so dangerous storing information in app in app storage slash user defaults. The key chain is the right place to store important credentials, And it's so hard to use. I mean, it's bafflingly hard to use and really easy to get wrong. And so okay.
好吧。也许 SwiftUI 自然地无法为钥匙串的 API 找到一个很好的拼写方式,但至少给我们一个钥匙串工具包,能优雅而简洁地封装所有复杂的细节,让最简单的选择始终成为最佳选择。
Fine. Maybe SwiftUI can't find a great spelling for the API for the keychain naturally in there, but at least give us a key chain kit that wraps all the horrors beautifully and simply and makes the easy choice the best choice every time.
我想到了一个类似霍默·辛普森的表情包,从前端到后端,前面是他站在那里的样子,双手叉腰,然后在后端,他把全身的脂肪都聚在一起,让自己在前端看起来很好看。就像这样,我们对钥匙串也需要这样的效果。
I'm thinking of the Homer Simpson meme that's, like, front end to back end, where it has him on the front with, like, his hands on his hips, and then in the back end, it's him putting pulling all his fat together so that he looks nice on the front end. Like, we just need that with Keychain.
是的,这在苹果的世界里其实挺常见的。你看像 Core Foundation 在 Foundation 之下,我们在 UIKit 之下使用 SwiftUI,SwiftData 背后是 CoreData,TextKit 背后是 CoreText,等等。
And that's look, that's kinda normal in Apple land. You look at things like core foundation sits below foundation. We have UIKit below SwiftUI. We have CoreData behind SwiftData. We have CoreText behind TextKit and so forth.
拥有非常硬核、非常严肃、通常基于 C 的 API,然后再在其上封装一层,甚至再往上再封装一层,以提供更现代的、更易用的数据 API,等等。这种做法非常非常普遍。请给我们同样的东西。如果你们不能在 SwiftUI 中解决这个问题,至少在钥匙串工具包中解决它,让它成为官方的、所有人都能用的东西。
It's very common to have hardcore, very serious, often C based API and then a layer over it, And often a layer above that again to have even more modern, so data API, whatever. That's very, very common. Give us the same thing. If you can't solve it in SwiftUI, at least solve it in a Keychain Kit wrapper. It's official for everyone.
我这里的小问题又是一个小而简单的功能。ScrollIndicator 的 flash on appear 是 iOS 18 中新增的 API,我相信是这样。但它只适用于 ScrollView,不适用于 List。我真的很希望它也能支持 List。List 在展示数据方面非常棒。
My paper cut here is going to be another little simple one. Scroll indicators flash on appear is a new API from iOS 18, I believe. It only works on scroll view, not on lists. And I really wanna have it on lists. Lists are great with showing data.
让我也能在 List 上闪现滚动条,请了。
Let me flash the scroll bars with list, please.
等一下,flash 是什么意思?是指滚动指示器吗?我不确定我了解这个 modifier 是什么样子的。
Wait. What does flash mean? Like scroll indicator. I don't think I've I don't know what this a p this modifier is.
嗯,是的。你会在很多地方看到它。比如,去任何一个……我们随便选一个应用看看。打开一个应用吧。
You well, yeah. So you'll you'll see it all over the place. If you go to, like, the any let's look. Pick an app. Go on.
给我一个做了愚蠢事情的应用。好了。比如在你的设置应用中
Give me one app that does a correctly stupid thing. There we go. Alright. So on your, like, settings app, for example
好的。
k.
当你进入 iPhone 上的“通用”设置,是的,你会看到当你滑动“通用”屏幕时,右侧的滚动条会闪烁显示。
When you go to general on your iPhone Yeah. You'll see as you move the general screen, the scroll bar flashes on the right.
是的,好的,所以它消失了。
Yes. Okay. So it disappears.
它会出现。
It appears.
它又出现了。
It's coming back.
消失了,是的。顺便说一下,你可以滚动这个界面,这个小小的提示说明它是可以滚动的。但你在有 50 行的列表里是做不到这一点的。
Disappears. Yeah. Just just just by the way, you can scroll this. The little hint is this is scrollable. You cannot do it in in fifty y lists.
这非常烦人。
It's very annoying.
哦,我倒挺喜欢这个的。
Oh, I do like that.
是的,从 UIKit 最开始发布的第一天起就有这个功能了,它会以一种命令式的方式让滚动条闪烁提示,请把它加上。但它只在高度为 50 的滚动视图中起作用。不管怎样,继续下一个话题。Dave Pletier 提到,他们希望能有一个官方的云存储属性包装器。
Yeah. It's been there since day one on UIKit with an actual imperative flashy scroll bars, please. But it only works in 50 y scroll views. Anyway, moving on. Dave Pletier said, they'd like to see an official cloud storage property wrapper.
是的,拜托了,拜托了,拜托了,拜托了。
Yes. Please. Please. Please. Please.
拜托了。我真的非常希望如此。目前,如果你的应用存储或其他任何东西存在年份默认值,这些数据仅在本地设备上保存。如果你想切换到云存储,并在 iPad 和 iPhone 或多台 iPhone 之间进行同步或其他类似操作,你必须使用旧的 NS 通用键值存储(NS ubiquitous key value store)。
Please. Please. I would love this so much. Right now, if you have year defaults with app storage or whatever, it's saved locally on device only. If you wanna switch across to cloud storage, synchronizing across iPad and iPhone or multiple iPhones or whatever, gotta use the old NS ubiquitous key value store.
这个 API 名字本身就是一个长口难念的事实,已经说明了使用这个 API 的体验是怎样的。好吧?要么让我传一个值到应用存储,比如说,可以自动同步这个值,或者其他类似的选项;要么提供一个修饰符,说明所有带下划线命名的内容都自动同步;或者直接给我一个云存储选项。我都可以接受。请至少给我一个解决方案,拜托了。
The fact the API name itself is a mouthful tells what it's like to use this API. Okay? Either let me pass a value to app storage, say, yes, sync this more automatically, whatever, or set a modifier saying everything sync underscore named synchronized automatically, or give me at cloud storage. I don't mind. Give me something for this one, please.
数据同步。这是最难实现的事情之一,但我们每个人都会以某种不同的方式去实现它。
Syncing data. It is the hardest thing to do, but we all do it some different way.
我们收到了大量关于 Swift 数据的回复,这并不令人意外。来自科罗拉多州的 Alex 说,对我来说,Swift 数据的一个难点在于动态过滤和排序。
We had a whole bunch of replies about Swift data, unsurprisingly. Alex in Colorado said, for me, it's a difficulty of dynamic filtering and sorting of Swift data.
没错。这就是问题所在。Swift 数据确实仍然存在缺失的功能,我认为很多人不使用它的原因也在于此。我们使用 Swift Data 或 Core Data 是为了保存数据,它比用户默认值(User Defaults)和 Codable 更加优秀。因此,我们最想做的事情就是很好地实现数据的过滤和排序。因此,目前 Swift Data 还无法实现这一点,是一个非常恼人的小问题。
Yes. This is the thing. Swift data is definitely still missing, but I think a lot of people don't use it for this reason because we use Swift Data or Core Data as a way to save data that is better than user defaults and that is better than codable. So the main thing we wanna do is filter and sort data well. So not being able to do that yet in Swift Data is a 100% paper cut.
当 SwiftUI 刚推出 Core Data 支持时,实现这些功能也非常困难。但在 iOS 15 中,他们为获取请求(fetch request)添加了一个简单的属性,允许你声明 NS 断言(NS predicate)和排序描述符(sort descriptors),并以命令式的方式更改它们。现在我感觉 SwiftUI 团队似乎不太愿意将这个特定的 API 重新添加到 Swift Data 中,因为这种做法是以命令式的方式更改结果中的一个排序属性。然而,目前我并没有更好的替代方案。
So when SwiftUI launched with Core Data stuff, it this was also very hard to do. But then in iOS 15, they added a little property to the fetch request saying, here's your NS predicate. Here's your sort descriptors to change them imperatively. Now I get the impression that SwiftUI team are not keen to re add this particular API to Swift data because it is imperative to change this thing as one sort of property on the result. However, I have no better option at this time.
问题在于,当我与苹果的工作人员交流时,他们说,哦,我们并没有从很多人那里听到这样的反馈。不对。我经常听到这样的声音。人们真的希望排序和过滤能够变得更加简单、更加方便。各位,如果你现在正在收听这条信息,并且你遇到了这个问题,那么你会发现目前在 Swift Data 中动态地进行过滤和排序是非常困难的。
And the problem is when I talk to Apple folks, they're like, oh, we haven't really heard that from many people. No. I hear it all the time. People really want sorting and filtering to be much, much easier. Folks, if you're listening to this message right now and you hit this problem, it's very, very hard to filter and sort things dynamically into data.
请务必提交反馈。用你的反馈来投票。告诉苹果,这个问题对你来说很重要。否则,它永远不会得到改善。
Please file feedback. Vote with your feeds. Tell Apple it matters to you. Otherwise, it's never gonna change.
是的。我最近在 iOS 18 测试版阶段提交了多个反馈,包括 Vision OS 相关的反馈。因为我确信他们希望借此机会修复很多问题。我曾提交了一个关于文档中拼写错误的反馈,他们随后修复了它,并告诉我是在哪次转换过程中修复的。所以他们确实在关注这些问题,尽管是否修复取决于具体的框架,但他们确实在努力改进。所以,去提交反馈吧。
Yeah. I filed several feedbacks lately within the iOS 18 beta phase and, like, Vision OS, especially because I'm sure they wanted to fix a lot of stuff with that. I filed a feedback about a typo in their documentation and they fixed it and told me that they fixed it in which ex conversion they did. So they looking at things, whether or not it depends on the framework, but they are trying to fix things. So it's like file the feedback.
否则,你就是在对着虚空大喊,而他们根本不会知道这个问题的存在。
Otherwise, it really is screaming into the void and they don't know about it when nobody tells them about it.
我这里的小建议是,希望能在 SwiftUI 中使用数据扫描器视图控制器(data scanner view controller)。这个功能在 iOS 16 中被引入,原本是为了非常非常方便地扫描二维码之类的内容,但奇怪的是它只支持 UIKit。这是一个仅限 UIKit 的 iOS 16 API,而 SwiftUI 早在三年前就已经发布了。因此,我现在还在维护一个叫做 CodeScanner 的大型 GitHub 项目,有超过一千颗星标,大家用这个库来轻松地从 50 年代以来就很容易地扫描二维码、条形码等。我不想再维护这个仓库了,朋友们。
My little paper cut here is I'd love to see data scanner view controller exposed in SwiftUI. This is introduced in iOS 16 to make it very, very easy to scan things like QR codes, but only from UIKit for some reason. It's a UIKit only API from iOS 16, which is three years after SwiftUI was announced in the first place. And as a result, I still maintain this huge GitHub repository called CodeScanner over a thousand stars where folks use this library to scan QR codes and barcodes and similar from 50 y easily. I don't want to maintain that repository anymore, folks.
你们已经有了这个出色的 UIKit API,请把它带到 SwiftUI 中吧。
You've got this amazing UIKit API. Please expose it in SwiftUI.
这就是我们学到的。我们仍然需要了解一些 UIKit 的知识。
That's what we've learned. We still have to know UIKit somewhere.
某些地方。天哪,这期节目里有太多抱怨了。这真的很……
Somewhere. Gosh, there's so much complaints episode. It's really
这现在有点消极了。
This is now negative.
不。它就是消极了。听着。听着。如果我们不在乎,我们就不会谈论它。
No. It's it's negative. Look. Look. If we didn't care, we wouldn't talk about it.
我们之所以谈论这些问题,是因为它们对我们来说很重要。我们希望这个已经很棒的东西变得更好。
The fact we're talking about these things is because we that matters to us. We wanna make this great thing even better.
确实如此。
It does.
Kubasilakovsky 表示希望 Swift Data 能够完整支持存储单个或多个枚举属性,并支持对它们进行过滤。这是一个具有挑战性的问题,因为 Swift Data 允许你将像结构体这样的可编码对象直接以 JSON 的形式存储在你的类 SQL 行中,当数据保存到磁盘时就是如此。这非常聪明,真的非常聪明,但也带来了一些有趣的问题:突然之间你无法读取这些看起来本应可读的内容。它们是枚举,诸如此类的东西。
Kubasilakovsky said they wanna see full support for storing single or multiple enum properties and filtering on them in Swift Data. This is a challenging one because Swift Data lets you store codable objects like structs and similar as JSON directly inside your SQL like rows when it saved out the disk. And that's really clever. It's really very clever, but opens up interesting problems where suddenly you can't read these things that look like they're readable. They're enums, whatever.
不。当它们被展平为 JSON 并存储在数据中时,它们就失去了枚举的特性。因此,有时候你会说,哦,对这个键路径进行排序,但它无法排序。它会在运行时直接崩溃,因为这种方式实际上不可行,这确实令人沮丧。
No. They they kinda lose their enum ness when they flattened out the JSON in the data land. As a result, sometimes you say, oh, yes. Sort by this key path, and it it's not sortable. It'll just crash at runtime because it's not actually doable in that way, and it is frustrating.
哦,这下明白为什么这很难实现,也明白为什么这个功能还没出现。但我们还是希望它能存在,因为,是的,我们就是想把数据保存下来。好,现在我们想根据值来排序。这一直都是我们不断保存数据的全部意义所在。所以我们希望可以以不同的方式对数据进行排序和筛选。
Oh, that makes that makes sense why that's hard and also why it's not there, but it's we still wish it was there because, yeah, we're just like, save save the value. Okay. Now we wanna sort on the value. The whole point of, like, saving data all the time. So we wanna sort it and filter it in different ways.
是的,这是在 Core Data 和 Swift Data 之间令人有些困扰的过渡地带。虽然通过数据转换已经很好地掩盖了这个问题,但目前来说还差那么一点火候。
Yeah. It's that uncomfortable bridge between core data and Swift data. It's been papered over with this transforming of data very nicely, but it's still not quite there yet.
就像一个盒子里还有一个盒子。我们需要再封装一层。
It's like a box in a box. We need to wrap the box even, like, one more time.
是的,我们需要的是 Swift Data Kit(套件)。我这里的小痛点是,我特别希望 SwiftUI 能有一个轻摇手势的修饰符。在 UIKit 中实现这个功能非常简单,但目前 SwiftUI 还没有这样的修饰符。
Yeah. Swift Data Kit. That's what we need. My little paper cut here is going to be, I would love to have a little shake gesture modifier in SwiftUI. This is very easy to do in UIKit again, but there is no current modifier for SwiftUI.
你只能从 UIKit 那边进行封装,这有点遗憾。所以我希望看到一个像 onShakeGesture 这样的修饰符。大家来一起呼吁吧,这应该只是五分钟就能搞定的工作。
You've gotta wrap it from UIKit land, which is a bit of a shame. So I wanna see like an on shake gesture modifier. Come on, folks. That's surely that's like five minutes of work.
很简单,对吧?就像所有事情一样,只要做起来简单就好。
It's easy. Right? Like everything. It's just easy.
Perry 说过他们希望 Swift Data 能有共享功能。
Perry said they want to have Swift data at sharing features.
我特别赞同这一点,是的,我还有另一个副项目,现在躺在墓地里,不知道以后会不会复活。我有很多应用创意,大概列了20个点子。如果有人真想开发其中一个,尽管联系我。我有很多这样的想法,真的很多。
I wanna clap to this one because, yes, one of my other, you know, side projects that's sitting in the graveyard that may or may not, like, one day come back. I man, I have a list of, like, 20 app ideas. If somebody really wants to build one, like, hit me up. If I I have a lot. I have a lot of them.
但其中有一个项目,我想尝试使用 Swift Data,这样我就可以开始真正使用它了。虽然我对 Swift Data 的基础知识有所了解,但还没有在实际应用中深入使用过。我们在一个自由职业项目中使用了 Core Data,因为那个项目涉及的数据量实在太大了。而我想要开发的应用程序中,一个主要功能就是类似共享购物清单这样的东西,类似于共享模型。比如,两个人共享一个清单。
But one of them, though, I wanted to use Swift Data so that I could start using Swift data. Like, I know the basics, but I haven't used it in-depth with, like, in an actual app. But we use Core Data in one of my freelance projects because it's crazy amount of data. But then Swift Data, one of the prime features of the app that I want to make is, like, a shared grocery list kind of thing, like similar model. It's like, oh, let's just share this one list between two different users.
但目前 Swift Data 还做不到这一点,因为数据同步本来就是个难题。
That's something we can't do with Swift Data yet because syncing data is hard.
是的。每次我看到这些请求进来的时候,我总是会想,苹果公司到底有什么原因导致他们还没有实现这个功能呢?你看,如果很简单的话,那它在第一版就已经完成了。对吧?如果在第二版中实现起来很轻松,那它早就实现了。
Yeah. I I always try and think about when I see these requests come in, what might it be that holds Apple back from doing this thing already? See, if it was easy, then it's done in version one. Right? If it was trivial for version two, if it is done.
对吧?这里一定有什么原因在阻碍他们。是他们有更好的想法吗?他们想再迭代优化一下?还是说用可观察模型实现这个功能其实挺难的?
Right? Something's holding them back here. Is it they have better ideas? They want to iterate on some more? Is it actually this is quite hard with the observable model?
我不确定,但我知道大家非常期待这个功能。所以希望在大约九个月后的Swift Data 3中能够实现。我这里特别希望看到的是,在SwiftUI中实现快捷操作能够更加简单。再说一次,目前有一个非常底层的UIKit API,或者是一些property list配置文件,比如info.plist。
I'm not sure, but I know folks are crying out for this one. So hopefully, in Swift Data three, in about nine months or so. My pick up here is going to be, I would love to see quick actions being much easier in SwiftUI. Again, there's a real hardcore UIKit API right now or property list stuff and info. Plist.
这部分应该变得更友好一些。再也不用去字典里到处查找东西了。举个例子,我只需要声明:这就是我想要的快捷操作,执行它就可以了。这样会更简洁、更友好。最后我们还有一个来自Tim Schmitz的关于Swift Data的建议。
It should be much much nicer. No no no more else digging around in dictionaries trying to find stuff. Let me say, here's my quick action on this, do that, whatever. Much nicer. And we have one last Swift data one from Tim Schmitz.
希望Swift Data在视图之外也能有更好的支持,尤其是提供一个类似于NSFetchResultsController的功能。对于不了解的朋友来说,@query宏用于查询Swift Data数据,但它只能在SwiftUI视图中使用。如果你在一个普通的类中,比如某个ViewModel中执行查询,虽然你也可以这么做,但数据不会动态更新。因此所有的变更,包括插入、删除等操作,都必须手动完成。这非常困难。
Better support for Swift data outside of a view, most notably an equivalent to NSFetchResultsController. So for folks who don't know, the at query macro for querying Swift data only works inside SwiftUI views. If you make queries from inside some regular class, like a ViewModel somewhere else, you can do that, but it won't update dynamically. And so all the changes, all the insertions, deletions, whatever have to be done by you, by hand. It's very, very hard to do.
这也使得单元测试几乎无法实现。
And it makes things like unit tests almost impossible.
是的。目前,将Swift Data用在视图之外的功能我们还没有。就像你说的,无法做单元测试,所以我们只能寄希望于它大概能运行起来。它大概能适用于Swift Data最基础的使用场景,也就是你自己保存一些数据,并且可以同步到云端。目前来说,这是Swift Data唯一能胜任的场景。如果你想要做任何共享或者公开的功能,都无法实现。
Yeah. Right now, separating Swift data outside of your view is something we don't have. So, like like you said, it's can't do the unit test, so it's we just, like, hope that it kind of works. So it kind of works for, you know, your basic use case of Swift Data of using it to save some data for yourself that can be synced to the cloud. That is kind of the only use case for using Swift Data at the moment because if you wanna do anything shared, you wanna do anything public, can't do that.
另外,你还得祈祷你的Swift Data和视图配合良好,而且你做的事情可能还比较简单。一旦你想在视图之外进行过滤、排序,然后把它放到视图模型或者其他对象中,你就卡住了。
And then, also, you have to hope that your Swift data works with your view and you're doing something probably simple because once you wanna filter sort and separate out of your view and put it in a view model or some other object, you're stuck still.
我这里还有一个小问题,我称之为“纸割伤”(看似小问题,实则可能很麻烦)。据我所知,这可能需要大量的工作。但我真的很希望可以将Metal着色器从字符串中编译出来。我知道这个需求很冷门,甚至是在冷门中的冷门中的冷门。
And my little paper cut here I say paper cut. This could be a lot of work for all I know. I would love to be able to compile metal shaders from strings. I know that's niche. And that's like a niche within a niche within a niche.
但我真的很想做一个类似Metal游乐场的小工具,你可以直接写Metal代码,按下运行,立刻就能看到另一边的效果。那会非常有趣。通常情况下,我们会把最后的发言权交给我们的听众。但这次,我想自私一点。我这里还有太多小问题想提了。
But I'd love to make a little sort of metal playground where you can just have a go at metal code, press play, and see apply straight away on the other side. That'd be so much fun. Now normally, folks, we give the last word in an open bat to one of our many listeners. This time though, I'm gonna be super selfish. I have so many little paper cuts here.
这并不是一个简单的文档问题。我想在这里表达一下我的一个观点,一个小小的不满。问题是这样的,如果让我访问 Swift Playgrounds 所使用的 Swift 编译器,我就能开发一个开源应用,让天使都为之歌唱。
This was not a paper cut. I wanna end on one of my things here, one of my little grievances. And it's this, give me access to the same Swift compiler used by Swift Playgrounds, and I'll make an open source app that will make angels sing.
感谢大家聆听我们所有的抱怨。也请务必告诉你的朋友这个播客,我保证其他的节目比这一集更积极一些,但这是因为我们在乎。再次感谢大家的收听。记得订阅、推荐给朋友,当然也欢迎留下评论。
Thank you to everybody for listening to all our grievances. Be sure to tell your friends about the podcast. I promise they are more positive than this one, but it's because we care. Thank you again, though, for listening. Be sure to subscribe, tell your friends, and, of course, leave a review.
下一次的开放话题是,请告诉我们你的应用。你在开发什么?为什么我们应该下载它?就让我们暂时停止抱怨吧。下次我们会分享一些更积极的内容。再见。
Our next open ballot, tell us about your app. What are you working on, and why should we download it? That's enough of us complaining. We'll say something more positive next time. See you.
再见。你可以改变主意的。
Bye. You can Change your mind.
这就是软件。谢谢大家。
That's software. Thank you.
关于 Bayt 播客
Bayt 提供中文+原文双语音频和字幕,帮助你打破语言障碍,轻松听懂全球优质播客。