50: It has a learning curve like a brick wall
It's also the 50th episode.
It is, it is actually. Yeah, I've seen this coming out and completely forgot about it again.
It is. Happy, happy anniversary.
The podcast will...
Happy 50th anniversary, yeah.
I think I made this joke before, right?
This podcast will soon eclipse our age in terms of episodes.
Well, I am actually 50 right now.
Yeah, exactly.
So it is... as of next month, it will be older than me.
[laughs]
But no, it's been a bit of a journey.
I don't know whether we actually set out to...
In fact, I know we didn't set out to make a podcast.
It just kind of morphed into one over time.
It started as a little kind of chat about what we were doing.
We even had guests on the first few, which I do miss having guests, actually.
I think we should consider bringing people on occasionally
because I think it's good to get other people involved.
But yeah, it's changed a lot since the very first days back on Twitter Spaces,
which is where we started it.
And then, of course, we kind of transitioned into being...
I hesitate to say a proper podcast because I'm not sure I'd give it that,
but certainly I'll take it a little bit more seriously.
Well, it is listed on Apple Podcasts, right?
So that absolutely makes it a proper podcast.
Yeah.
The requirements for being listed as a podcast there, though, are very, very minimal.
Yeah, you're saying that the validation isn't as tight as it is
to get a package on this with Package Index.
Tim Kirk doesn't go and listen to your podcast if you want to be on that list.
[laughs]
He'd have a lot on his hands to listen to all of them.
[laughs]
I remember.
In fact, it was at the last Swift Server Conference,
which I think was actually 2022, the last one I was at.
We'd just switched across to using...
doing the podcast as a kind of actual podcast rather than Twitter Space,
but we were still recording on the microphones we were just using for those early ones.
And somebody came up to me at the Swift Server Conference and they said,
"I really like the podcast, but please fix your audio."
[laughs]
Ooh, harsh.
[laughs]
I like "but" never ends well, does it?
[laughs]
I was well aware of the...
And I'm not sure who it was.
I didn't get their name.
It was a very brief interaction.
So if that was you and you're still listening, I did try and fix their audio.
In fact, I've put many, many, many hours into fixing our audio.
[laughs]
If that was you, I'd love to see if you think it's fixed.
So please get in touch.
[laughs]
Nice.
So yeah, 50 episodes.
It's a milestone of sorts.
Well, speaking of the Server Side Swift Conference,
actually, there was...
Just after we recorded the last one,
I went to the last episode of our podcast.
I went to the Server Side Swift Conference in London.
It was great.
It was great to see folks.
Great talks.
It was a two-day conference this time.
I think it was one day only in '22,
which was the previous one.
There wasn't one in '23.
Yeah, great lineup, great news.
So we actually got an Apple announcement of sorts again.
There was a talk by Tony Parker and Ben Cohen.
It was called "Swift and Interoperability".
"Interoperability".
God.
See, that's easier for you to say.
[laughs]
And they announced Swift Java integration,
which I found fascinating and great to see.
So what this is about is about calling into Java from Swift
and vice versa, calling into Swift from Java.
And this is early days for the project.
We'll drop a link in the show notes.
Also open source again,
so you can follow along as stuff is being developed.
And it feels like Swift is really gaining
more and more superpowers when it comes to
interoperating with other languages.
And there was quite a bit of excitement
around the conference as well,
when people were talking about it afterwards,
because I can imagine there must be lots of
big Java deployments that are perhaps sort of eyeing,
you know, a future replacement.
Like Swift is supposed to be one of the successor languages
for C++.
I wonder if there's the same sentiment for Java,
because there are lots of nice things about Swift
compared to Java.
And I've just thinking in terms of memory,
just today I looked at the memory consumption
of our web application,
which is a Swift on server project with 270 megabytes.
And I don't think even that's particularly small.
I think we have a couple of caching things happening
that makes this a bit bigger than it would necessarily need to be.
But I think in the Java world,
that's a dream, you know, to have that as your memory size.
And I think that might be really interesting
for lots of projects as a way to transition.
And in particular, because it really allows you to go bit by bit.
So we can do this function by function,
because you can call out into new code,
and it really transitions slowly.
And I think that's one of the greatest things
with all these transitions that Apple always do,
is making sure that you can do this byte size.
And memory efficiency, especially on the server,
is really, really important,
because it's one of the things
that hasn't really come down in price very much
in the last few years.
Large servers with lots of memory are still very expensive.
And memory seems to be the thing that you actually pay.
That's what bumps the price up.
Yeah, absolutely.
Our Linux builders are actually quite big in terms of memory,
because builds often use a lot of memory.
And CPU-wise, we wouldn't need the...
I think it has an eight-core machine,
which we wouldn't necessarily need.
But the memory really drives up the price in that instance.
Same with our Mac build machines.
They've got an enormous amount of memory.
And yeah, it's an expensive thing to do.
Yeah.
I think it's great to see Apple and the Swift team
making these announcements at these community events.
And especially, I don't know, I presume it was Tim
and his team that were responsible for doing this,
but they were incredibly quick getting the video out
so that the announcement could actually be public,
because that was the only downside to it a little bit.
I heard about the announcement,
but not being at the conference,
I wanted to write about it,
but I had almost nothing to go on to actually write about it.
I could see the repository, of course,
and the repository readme is useful,
but it's not really the announcement.
It doesn't give you any of the context or anything like that.
Now, luckily, the Swift Server Conference
did publish their videos within a week.
So by the next week,
I was able to link to the video as well.
But I did have to kind of write about it a little bit blind.
But I love that they're picking these venues to,
like last year or in 2022,
the announcement of the foundation
and this year with the Java interop.
Great. I applaud it.
But if I could applaud it
with also a blog post published at the same time,
that would be even better.
[laughs]
Yeah. And speaking of the Swift Foundation announcement,
Tony spoke to that a bit
and gave a bit of a summary of what happened there
and that the transition effectively is complete,
like Swift Foundation is now shipping the open source one.
That just happened during the Swift 6 beta phase
that they switched over to the open source version
of Swift Foundation, which is really nice
because it aligns the APIs with the Linux world.
This is a place where we've seen a couple of times
when stuff wasn't quite there yet.
So that's great to see.
A few other talks I wanted to give a quick shout out.
And this was a server-side Swift conference,
but the reason I'm mentioning a few here
is because they're more general.
They're not server-specific really.
Daniel Steinberg had a nice talk
about when to make a macro.
Really great talk going a bit into the details there.
Franz Busch talked about leveraging
structured concurrency in your applications.
Again, giving a nice summary how to transition over,
adopt concurrency, Swift 6 concurrency.
Babit Vege, a bachelor student,
gave a talk about stop worrying about roots
with open API generator.
I found that nice because while open API generator
is obviously server-specific,
you might have need for that.
For instance, if you stand up a mock API,
you're developing an app, and these days,
I don't think, hardly any app gets developed
right without talking to an API.
And you might actually want to stand up something
that you can connect your app to
while maybe production doesn't exist yet
or you want to inject some data,
have some example data for testing
or for generating screenshots, stuff like that.
Depending on how you want to do that,
it might be really nice to just take these
open API specification,
just run it through that generator
and bring up a server that you connect to.
So she gave a talk about that,
how to use the open API generator.
And then finally, Nick Lockwood with a really great talk.
"So you think you know Swift?"
And that was one of these where, you know,
there's lots of things in Swift that seem weird
and you sort of struggle with,
especially around strings is like the classic example.
Why can't you index into a Swift string?
And he explains why there are these,
why it is the way it is,
and also brings up a couple of things
that maybe people don't even know,
because Swift is a big language,
there's stuff that you don't typically come across.
So that was a set of talks
I wanted to mention from the conference.
There were quite a few others, more service specific,
but they're all great, they're all worth checking out.
- That's great. - And we'll add links to the show notes.
Sure, yeah.
I also had a note from...
Well, so in the previous episode,
one of my packages that I talked about
was called Chip8Kit, I think,
or Chip8 something.
And it was about an emulation
of an old computer system called a Chip8.
And I had a message from Mirza,
who also got mentioned last episode
as the person who contributed to the Swift package index,
the forked from functionality that's now live on the site.
And he dropped me a message on Discord
and told me that a couple of years ago,
he had built a Chip8 emulator,
not as a Swift package, but as an iOS application.
So if you were curious about the Chip8 system
that we talked about last time,
and wanted to play...
Well, the screenshot on the Git repository
is playing Pong on the Chip8 system.
Or Tic-Tac-Toe, I think, as well,
or maybe Snake as well.
If you wanted to have an iOS version of that,
I think it's worth to mention that there is this repository,
and we'll put a link in the show notes to that as well.
So thanks for the update on that, Mirza.
Nice.
Another thing worth mentioning is a new repository.
I think it's--yeah, it's fairly new.
It's GitHub Actions Workflows repository on Swift Lang.
And what this does, it collects typical things
you might want to run in your CI system.
And I find that really nice because I tend to,
you know, sort of copy bits around
from my previous repositories when I need something
or from, like, well-known repositories
where I know they have solid setup,
and I just steal bits and pieces here and there.
But what this does is sort of--I think the idea is there
for this to be the way to get started
with a CI setup for a Swift package on GitHub
with GitHub Actions.
It has the typical thing you'd expect,
like running tests.
And it also has something which they call soundness checks,
and that's stuff like formatting checks, linting,
license checks, you know, that your files have
license headers and that stuff.
And you can configure this.
You know, you can use these.
You can--I think there's a YAML file you can use
to specify which parts you want to run,
that sort of stuff.
It's great to see that appearing.
The only problem right now, as far as I could tell,
this is currently only supporting Linux,
so if you need to run this on macOS,
you'll have to wait a bit longer for that support to appear
or make a contribution to add it.
Of course, yeah.
It's also probably worth mentioning at this point,
have you heard of a tool called Danger?
Yes, I have, yeah.
Yeah, so Danger does some similar things to that,
like checking license terms and other things
that you can configure that it will check
as a kind of sanity check before your code goes in.
And I think that--I believe that does support Mac as well.
It has been around for quite a while,
so it's probably just worth mentioning that as well
at this point.
Yeah.
So that's kind of action workflows,
and we'll add the link to the show notes.
So are we planning to implement some of those checks?
Well, yeah, I think it might be worth looking
at which parts we could use.
I actually added an issue to our issue tracker
to at least explore what the options are.
I had a quick scan.
There's quite a lot in there already,
and I think some of it would certainly be useful,
like the soundness checks license.
I mean, I think we're pretty--we don't add new files
that often these days, and I don't think we miss
adding the header, but just having that check in there
would be nice.
Formatting, certainly.
I think you wrote about formatting as well
on "Iris Dev Weekly" last week, didn't you?
I did, yeah.
A rather opinionated piece, which I got lots of feedback
in both directions on.
Oh, do say.
There was more--
About formatting.
[laughter]
There were more--there was more people in agreement
with me than against me, but it was about 70/30,
I would say.
Yeah, I'd love seeing something like that be around,
like integrated and running by default.
I was nodding along as I read your comment
about formatting on save.
I'm glad at least we're in agreement,
because that's a good start.
Somebody did actually drop me a note saying
that they had published an Xcode plugin
using the new single-file Xcode extension architecture
that you combine Command-S to, and effectively what it does
is it runs Swift format instead of saving,
but of course the Swift format then does the save.
So effectively, you can do what I was asking for.
And if anyone's clueless about what we're talking about here,
just go and read the latest issue of iOS Dev Weekly,
which is issue 682, and I talked about Swift format
and code formatting.
But I think my point was--and that's--
an extension like that is fine, but my point was a bit bigger
than that in that I'd love to see--first of all,
I'd love to see a standard, and I don't--
nobody's going to agree on the standard,
but I'd love for Apple to just say,
"This is how we format Swift code,"
just like Go did, just like JavaScript did.
And this problem just goes away after somebody does that,
but it needs to be somebody who's with authority.
It needs to effectively be Apple who'd do it.
And then, of course, I would also love to see
auto-format on save, which is the key thing,
because at that point, you can just forget about formatting.
And I say this with experience, because I've had this switched
on in JavaScript and CSS for a very long time now,
and I don't even bother trying to get the indentation right.
I just type whatever I want and hit save, and it's done.
- Yeah, yeah. - It's so freeing.
It's great.
It's just a thing you don't have to worry about anymore.
It's great.
Anyway, so before you set me off on my rant again, let me stop.
All right.
And finally, I wanted to mention something really neat
that I saw on the Swift forums.
I think it was just yesterday at time of recording,
and there's a pitch up for the vector type,
which is a fixed-size arrays type,
and there was Caroy Llorente.
I think he certainly works at Apple,
and I think he's also one of the authors of the proposal
and the implementation.
He talked about--as you might imagine,
there's a discussion about naming on the Swift forums,
and he talks--
I just can't remember naming.
That should be quick and simple.
Inconceivable.
And he comes out in favor of the name vector
and tells a little story how they arrived at the name.
It wasn't actually named that initially.
And he says, "That very same day,
two separate groups of people independently realized
that copyability has now turned this type into a true vector,
and that vector is the obviously right name for this construct.
This made for a comical scene when members of the two groups
met later in the day,
fully expecting that they need to convince the other."
I thought that was really neat
when people actually independently arrive at the same conclusion
and then feel like, "Oh, God, I've got to convince someone
of a different name," which I can imagine.
We see these discussions happen all the time, right?
When people have settled on a name,
it can be really hard to convince them of a different name.
So, yeah, I found that really neat.
Yes, yeah.
Shall we do some packages?
Let's do some packages.
I've only got two, so I'm going to let you kick us off.
Sure thing.
I can kick us off with a package from Christian Selig
called TinyStorage.
And it's a simple, lightweight replacement for user defaults
that makes access a little more straightforward,
plus some niceties.
So the readme of this starts with a link to a blog post,
actually, where Christian was having some issues
with user defaults.
And I think it was largely around needing to access user defaults
kind of immediately at the app startup,
and there were some kind of inconsistencies there
with things not quite being ready when he needed them.
So I think he looked at building an alternative,
and it must admit it looks like he's done
a very thorough job of doing this.
So some of the features that it has, the primary one,
the first bullet in the list is relating to that point
that I just mentioned there, which is reliable access,
either on first reboot or in application pre-warming states,
TinyStorage will read and write data properly.
It's got a code on support, of course.
It's got a property wrapper for an app storage-like wrapper
that you can use in SwiftUI and things like that.
You can subscribe to notification center,
notifications when things change.
It uses OS log for logging.
So it's really -- and I think I listed like four or five
of the 12 bullet points that are in the features list there.
So it's quite a comprehensive package.
It is brand new, so of course, be a little cautious
with a package that is brand new,
because all brand-new code has bugs in it.
Of course it does.
It's only been in development for six days,
and I believe it's been out a few days ago.
So it is -- presumably it was a clean commit just before
the open source release, because I am sure it had development
before six days ago.
But, yes, it is -- oh, and it looks like it also has
a mechanism similar to app groups for sharing data
between your applications on the same phone,
so from the same developer.
I haven't looked into that in great detail,
but I just noticed it now.
So it looks great.
I mean, it's effectively user defaults, but different.
Yes, and I think it's worth calling out -- you mentioned it
in a quote from the readme.
I think it fixes one of these -- the problem that spawned
this whole thing.
I saw the blog post, and I think it's worth calling out
what actually can happen with stock user defaults.
When an app is launched in the pre-warming phase
or by some other means while the device is locked,
it can happen that user defaults isn't accessible
and then gets reset to the app's stock defaults,
and then you lose the data that's in it.
And that's the investigation that -- I think this triggered him
to write this replacement, which doesn't have that problem.
Right.
I believe the keychain can also get in that state as well,
because if the phone is locked and the keychain gets locked,
and if you're trying to access keychain in the background,
that can also be a similar problem.
Yes, or it might be -- I think user defaults can be --
they can have an attribute, whether they're secured or not.
It's worth looking into the details,
looking at that blog post that outlines what the problem is,
and this is apparently a real problem,
and presumably the package doesn't have that problem,
so that's nice.
The blog post is linked from the top of the README file,
so it's literally the first link in the file.
Yes. There you go.
So that's Tiny Storage by Christian Selig.
Nice.
My first pick is called Recap by Joe Fabicevic,
and you've also linked to this package in IoStep Weekly from Friday.
And this is a really nice "What's new" screen for your iOS app,
and it's iOS only.
I was actually surprised to see this.
It doesn't even call out iPadOS,
so I'm not sure what the state there is.
It's worth looking into if you need this for the iPad.
But it looks really simple to use.
You have a YAML file where you configure what should be on that screen.
You can give an entry, a title, a description, a SF symbol, name, and a color,
and then it does a really nice layout.
I mean, "What's new" screen, you know what these look like,
and all you really need to do is add the dependency
and write this little YAML file, and then it does it all for you.
And I think this is one of these things that is getting more important
because I hardly look at release notes in the App Store anymore
because I have, like for ages now, I've had auto-update enabled, right?
So apps just update, and I never see what's new.
And I do actually quite like these screens.
I mean, maybe not every small update needs a screen like that,
but if you have, like, bigger changes,
I think that's a really nice way to tell the user, you know,
"This is what's new. Have a look,"
or explain why something might be in a different place or something like that.
So a really nice package to deal with this aspect.
I really like this, too. I thought it was great.
And I think there's a couple of things worth mentioning with this.
I think you're not alone in not reading release notes anymore.
Nobody reads release notes because everybody--
because updates are on by default,
and I don't remember the last time I went into updates
to even see what was pending.
It just takes care of itself, and I never check it,
which means I never see any of the update notes.
It was never the greatest place to put really important information
because a lot of people never checked there.
And even if they did manually update, all they did was hit Update All.
So, yeah, it's never been the best place.
But one thing I liked about this is that you can actually page back
through previous--like it's almost a release notes,
a changelog system as well.
So, yes, you have the one that comes up on the screen when people launch,
but if they're interested, they can page back through previous ones
to see what happened to the app in previous updates.
So I thought that was a nice feature worth mentioning as well.
That's nice. I hadn't even seen that. That's great.
That's great.
So that's Recap by Joe Fabicevic.
My next pick is Location Radius Picker by Eman Basic.
And this is a UI view controller subclass.
So I presume you could wrap it in a UI view controller.
What's the wrapper class that you can wrap it into SwiftUI?
It's designed initially for UI kits rather than SwiftUI,
but it's just a really nice implementation of a control that you don't get
for kind of built in with UI kits,
which is selecting a radius over the top of a map kit map.
So you don't want to just select a single pinpoint on the map,
which I believe it does do.
If you want to give the application a X meter radius around a point,
then this is a really well-designed version of that.
And when you zoom the map in and out,
your selected radius also scales nicely with the map.
It also tells you how big the radius is.
So as you drag the circle out across the map,
you'll see that it starts as, you know,
you drag it once and it's a 50 meter radius,
and you zoom out a little bit and drag it again.
Now it's a two kilometer radius.
And again, what caught my eye with this is a fantastic demo video
at the top of the readme file, which is always really important
if you're building anything that has a visual component.
The very first thing you should do is show people what it looks like.
And it was that that caught my eye.
And yeah, I thought this was just a useful little thing
that you're not going to need this every day,
but when you need it, this seemed like a well-designed one.
Nice. That sounds great.
Okay. My second pick is called Swift Async Operations by Matsuji.
And I only got this GitHub handle here.
Unfortunately, GitHub itself only lists that name as well.
And that's a really interesting library that deals with an API
that I kind of struggle with.
I mean, it's fine, but it feels a bit...
I don't know how to describe it. I'll explain what it's about.
So Async Let is a simple way to start concurrent tasks, right,
in Swift Async Await land.
And you use that when you have a certain number of...
a fixed number of tasks that you want to fire off.
You know, for instance, you know I've got these two URLs to fetch,
and you do Async Let for both of them,
and then you await, and then they run concurrently.
Now, if you have a number n of tasks,
and you don't know an indeterminate number,
and you want to, for instance, create them,
spin off these tasks in a loop,
you would use the With Task Group API.
And that's the thing that I find really, like,
I don't know how to describe it.
Suddenly you need a lot of boilerplate,
where previously Async Let is so lean, right?
You don't even realize, maybe that's even a problem.
You don't realize you're spinning up a task,
but it's a really lean API.
And then suddenly when you need, you know, I don't have just two.
I have n. I need to...
I can't just write a for loop or something, or have a map,
and this is what this package does.
You then have to employ this whole With Task Group thing,
and then the group thing needs to do the add task,
and then at the end you have to await the results,
and there you'd loop.
It's a weird...
You know, you have this progressive disclosure normally,
and this feels like, oh, I'm progressively...
Boof, there's a truck. That hits me.
It's not really progressive.
It's like a cliff you're hitting.
A progressive brick wall.
Yeah, exactly.
So this introduces an Async Map and an Async For Each.
And I know For Each is controversial.
Some people argue it shouldn't even be in the language,
but there is sort of a reason why it perhaps should exist here
in this specific case, and the reason is that both these method calls
have taken optional parameter number of concurrent tasks
where you can control, like map over something,
Async Map over a collection,
and then you can say number of concurrent tasks,
and it'll fan out up to that concurrency
and do the things in concurrent tasks.
And Async For Each is the same, just not--
it's like a proper for loop without returning something like the map does.
I mean, obviously you could abuse map in that same sense,
but just API-wise, that's the distinction.
Now, I haven't looked at the implementation.
Take all of this with a grain of salt because there's lots of Async Awaits
stuff happening, and people are still finding their way
how to best do things.
I really wanted to highlight the package, perhaps not so much
as a thing you should jump and use immediately.
Certainly, if you need it, have a look at the implementation,
but also maybe in talking about whether the With Task Group API
could perhaps have a more sugary variant.
That is a bit nicer to use because I feel like I really--
A, I need to look it up.
I can't just write a With Task Group thing and then the awaiting stuff
at the end.
I need to look it up.
I can't-- for loop, I can write.
A map, I can write.
For each, I can write.
With Task Group, I can't.
I need to look it up.
And I feel like there's a-- that's telling me something.
I think that API could perhaps be easier,
and maybe that package has ideas what that API could look like.
Anyway, that's why I thought it was interesting.
Swift Async Operations by Matsuchi.
And it's worth mentioning-- you briefly mentioned it there.
On the topic, we quite often say when we're talking about packages here,
we quite often term them recommendations,
but all we're ever saying with these picks of packages is this is something
that we've found interesting.
This is not a, you know, we've checked through every line of code
and made sure that this package is perfect in every way.
Like some of the packages we've talked about today are, for example,
six days old, and they're being mentioned more as a notable event
rather than an outright recommendation because we can't possibly have used
all the packages we talk about on this podcast.
Although we try, if you look at the number of dependencies
in the Swift Package Index Server project, we are certainly trying.
Well, a lot of those dependencies come with vapor, right?
Well, I still maintain we are the Swift Package Index.
We have an obligation to just try them all.
And with that, it brings another episode to a close.
So I think we will call it a day there and speak to you next time.
And for now, we will say goodbye.
Yep. See you next time. Bye-bye.