40: This downtime was a joint effort
Well, there was a blog post that I read this week, which I thought was quite
interesting, which we may want to tackle first.
It was from Ander Dobo who works with Flutter.
I'm not sure whether he's on the Flutter team.
I think he is by the look of his profile on the blog post.
But it was a post around the progress of the Flutter and Dart package ecosystem,
which post titles like that always catch my attention.
At least in the last three years.
And it was actually quite surprising how big the Flutter package ecosystem is to me.
So Flutter's been around for, I don't know, several years now, more than five years, I would say.
I think when it first came around, a lot of people kind of thought it was just after React Native did its thing.
And fundamentally, it's actually quite a similar system.
It's based on Dart instead of JavaScript, but JavaScript is the fundamental language behind Dart.
I believe.
And it's a cross-platform framework where you can build applications using different technologies for iOS and MacOS and other Apple platforms, as well as Android and all the rest of it.
But then, I mean, I've paid attention to it a little bit over the years, but I've never used it.
But I've not really been paying close attention, I don't think, because it has a huge package ecosystem.
So we quite often do little quizzes here when we have stats like this.
So it's time for a little quiz.
Here we go.
Total package ecosystem size right now in Dart, what would your guess be?
We're about 7,000 on Swift at the moment.
Yeah, I'm pretty sure it's more because these ecosystems tend to be really active.
And if it's based on JavaScript, I guess there might be sort of, people might be conditioned into making smaller packages.
So are we talking in size?
Are we talking like number of packages?
Sure.
Yeah.
Yeah.
20,000?
50,000.
Okay, order of magnitude.
I'll take the point.
Yeah, order of magnitude is correct.
But actually, more impressive than that is the rate of growth.
So the post says that the ecosystem grew 26% during 2023, from 38,000 to 48,000 by the end of last year, which that's a significant growth.
And also, so they have a package index site as well, which I believe is kind of an official package index site.
Yeah, I'm not 100% sure on this, but I believe that, so on the homepage of pub.dev, which is their package index, it says supported by Google.
So I'm not entirely sure whether that means it's a Google, like it's under development by Google, or whether it's a similar situation to the Swift package index, where it's supported by the language owner, in our case being Apple, in their case being Google.
So, but I thought that was quite interesting, the amount of growth and also the amount of traffic.
So they give some traffic stats on the blog post as well.
700,000 monthly active users going to pub.dev, which...
Interesting.
But when you, did you say they grew how many, 26% year over year?
26%, yeah.
You know how much, I had the chance to look this up while you were talking.
Do you know how much we grew year over year?
That's a very, it's a very good question.
I...
It's a reverse quiz, this one.
Yeah.
Maybe it's because I'm closer to it, but it doesn't feel like our number of packages grew by 26%, but maybe I'm wrong.
You're wrong.
It's 27%.
27%.
That's amazing.
Go Swift.
I can tell you right now that we don't get 700,000 monthly active users on the package index.
Oh, did you say 700,000?
Because I thought you said 7,000.
I thought, well...
No, no, no.
We could, we could beat 7,000.
Yeah.
Yeah.
That's a, that's an enormous amount of traffic.
And, and I don't know, it's, there's not a lot more to this post.
But I thought that was really interesting seeing another package ecosystem really grow like this.
They also give some great, some kind of favorites.
They've got a Flutter Favorites program, which recognizes and helps developers discover the highest quality packages to consider using in their apps.
And they've, so this is, I think, a little bit like the Swift Server Workgroup incubation program where packages get nominated to, to be part of this Flutter Favorites.
And it says, right, Flutter Favorites are packages that have demonstrated exceptional quality, popularity, and community engagement, making them invaluable tools for Flutter development.
So that's, I mean, I think that's, that's, it's great to see other package ecosystems thriving like this.
And I thought it was worth highlighting to people who, here, who, you know, it's very easy when you're, when you're doing Swift all day to look inwards towards only what's happening within this community.
And I thought this was worth mentioning.
Yeah, it's definitely interesting.
I mean, there aren't that many language ecosystems around, you know, that you can actually compare.
And it's really nice to get these data points to see, you know, where, where Swift comes down to in terms of, you know, packages.
And I was surprised by that.
Well, then again, I'm not surprised because just way more JavaScript.
Well, then again, there's lots of iOS developers, right?
I mean, I wonder how big the developer populations are on either side.
I guess there's more JavaScript, right?
That is probably still, that's more people, but iOS is huge as well.
So, interesting.
It is.
Yeah.
Really interesting.
I think iOS and Swift in general had a little bit of a reset in their package ecosystem with Swift Package Manager being around for a little while.
But not possible to use within iOS and macOS projects for a while.
And so there was a little bit of a kind of reset that we had in this ecosystem that, I mean, Flutter and Dart are not super old technologies,
but I think they've been around a little longer than Package Manager.
Yeah.
Yeah, I mean, there's certainly that.
Although you could also argue it's not a reset in the sense that it onboarded lots of, there are ways to onboard lots of Objective-C and even C packages, right?
So it's sort of in quotes, cheating a bit by onboarding existing things as packages into the ecosystem.
But then again, that's the appeal of it, right?
There's just lots of tried and trusted legacy code that can be adopted and be used in Swift, which is great.
So, yeah, interesting.
One thing that they also do, which I quite liked was, they haven't actually published one for a couple of months,
but I guess we've had Christmas and the holidays get in the way the last couple of months.
They do a package of the week video, which looks to be very slickly produced.
It's kind of got this animation with it, and someone goes into one of the packages and kind of talks about it.
So there's obviously quite significant effort behind their package ecosystem.
They're putting a lot of work into it.
Oh, you're saying we need to beef up our YouTube game a bit?
If we do, it's you doing it.
I'll tell you that right now.
No YouTube career in the near future.
It's already the worst part of producing the podcast is making the YouTube video.
That's with it being a still, right?
Yeah, exactly.
Nice.
Well, we've also got a bit of a small piece of follow up as well.
Last time we talked about the benchmarking package.
And I thought I'd said it when I talked about it.
But when listening back, I realized I actually didn't spell it out explicitly that
this package allows benchmarking, a baselining of your benchmarks.
So effectively doing the exactly the same thing as you can do in Xcode when you
run your performance tests, your measurement tests there.
You can, I think you can right click on the test and you
can recall a baseline that then future runs are tested against.
And you can do the exact same thing here.
The advantage being it's now run via Swift PM.
So you can run it through your normal test machinery there and on Linux as well,
which is really nice.
And if you are interested in seeing how that works, the Swift Neo package actually has
a benchmark in it that use those baselines.
So take a look at that.
And thanks again for Joachim Hasseler for pointing this out to me after the podcast.
Oh, interesting.
Yeah.
There's one other thing that I want to talk about this week before we get to
package recommendations.
And that is that there's, I think, what is quite a famous kind of warning to all
software developers when talking about blogging.
And all software developers, I think, are susceptible to the fact that when they
decide to write a blog post, their first thought is, well, how am I going to write
the blog software that I'll then write my blog post in?
And there are so many pieces of blog software that have been started and then
have one post written for them and then never, never been posted to again, that
it's become a bit of a kind of a running joke that the first thing that a software
developer will do when wanting to write a blog post is start to write blog software.
Well, if you're a 10x programmer, you actually start writing an editor first, Dave.
Right.
So guess what I did yesterday?
Well, I know you've already seen the pull request.
I can't really fake surprise now because I've seen the commit history.
You've seen the pull request.
Yeah.
So yes, I rewrote our blog yesterday.
So there was a couple of reasons to do it.
We're actually, we're in a period of trying to fix some of our SEO at the moment.
We're having some, I think we've talked about it on the podcast before.
And so we're in a bit of a, certainly I'm in a little bit of a mission to fix up
several things and some of the stuff needed fixing on the blog.
And actually we've been in a pretty terrible situation where the blog previews
haven't been working for me.
I don't know whether you run the previews Sven, I presume you don't.
When you review the posts, I'm guessing you read them just the Markdown file, right?
I run the, I spin up the server.
So Visual Code has this thing where you can run a live server and I've often
spun that up and read them in the rendered output.
Oh, okay.
Interesting.
Now it's, I don't remember when I last did this.
The last one, I don't, I'm sure I didn't.
So I'm not sure if you're referring to this, this would have been broken.
I think it might've been a little while.
Yeah.
Okay.
Yes.
Yeah.
Our JavaScript environment needed some updates and it was fine.
It was fine in production.
Like when you run the final build of all the CSS and JavaScript, that's fine.
But there are some issues with it.
And also, you know, when we created that blog, in fact, I remember having the decision,
discussion with you about the decision on whether we should even do a blog.
And we didn't launch the site with a blog.
And it was only after a little while that we added one.
And I think it was a good decision, but I think it was, when we did it, we certainly,
it wasn't a hundred percent sure that it would last forever.
Like we needed to kind of prove the, do we actually post things to it?
And while we don't post super often, we post often enough that I think it's worth having,
like we use it semi-regularly.
Yeah, definitely.
Yeah.
But of course, when it's outside of the main project, the kind of maintenance of it falls
to one side because it's never the most important thing.
So a couple of reasons to bring it in, we can give it a kind of update and a refresh.
We also get to use all of the nice stuff that we have inside the package index.
So we can actually bring in like the supporters, which I put down the side of the blog index
and things like that.
Obviously all of the markdown comes across and we're even still using the same markdown
processor, which is John Sundells Inc.
Project.
So the rendering between the two, you know, one blog post to another should be identical.
And in fact, I've tested it today and everything is looking great.
Although it also made me find a whole load of problems that we had in the old blog posts,
which I've kind of fixed up as well.
So, yeah, now we have everything just under one URL.
Everything's on swiftpackageindex.com, no more subdomains.
There are obviously difficulties with going live with something like this, where you don't
want to just abandon your old URLs because people will have linked to those blog posts.
Even if it's just on social media, there will be traffic coming in through those old links.
So I have a plan in place for setting up permanent redirects so that all the old traffic comes
through and including, and this is something that it always, it's a little bugbear of mine
that when people do change their blog software, if you don't redirect your RSS URL, then the
people who were subscribed are suddenly no longer subscribed and they just don't know
that they're not subscribed because it doesn't error or anything.
So we're also going to redirect our RSS feed, of course, so that if you are subscribed,
you will stay subscribed.
Of course, if you'd like to update the URL, that's also fine.
But that redirect will hang around forever.
Nice.
Is that going to be done via Cloudflare or do we run something on the existing, the old
site, replace the old site with?
Unfortunately, the old site was running on GitHub pages and GitHub page does not support
redirects.
So we could do it on Cloudflare.
That was one thing I looked into.
Unfortunately, it needs a page rule on Cloudflare and those, if you've ever had a cheap or free
Cloudflare plan, they are very, very scarce.
So instead, I'm going to use a site which I've used for my stuff for years and years
and years now.
It's called Netlify and they have a free plan, which is extremely generous.
Like, for example, iOS Dev Directory runs and has always run off Netlify and several
other sites that I run are all hosted there and they do support redirect files and they've
been incredibly reliable for the years and years, easily more than five years that I've
been using them.
So they are great and we can just upload one little text file that says, here are a list
of URLs, here are a list of new URLs and it'll serve that forever.
Right.
And because it's the blog subdomain, it can just point to that site and redirect to slash
blog, I suppose.
Exactly.
Nice.
Yeah, that's exactly it.
And the main objective here is to get the SEO under one roof because those would be,
or those currently are separate buckets, right?
Exactly.
Yeah.
So I wouldn't say that's the primary reason.
I think the other reasons were actually slightly more important, but when starting to look
at some of the other reasons, it's like, well, I just need to, we just need to do this.
And it didn't take that long.
I started it kind of, I think, mid morning yesterday and it was pretty much done by the
end of the day yesterday.
Few little tweaks and cleaning up and stuff today, but it's not been a week's long project.
So hopefully I can be forgiven for writing a blog.
Nice.
Yeah.
I mean, I can see the appeal.
It's much easier than to preview something.
And the deployment process is the same one we use.
The slight downside I see is that it's going to take a little longer to deploy because
all our tests have to pass before we can merge.
That's our rule.
I mean, we could obviously, in the case of a blog, we could decide to short circuit that,
but that's the only downside I can see.
And that's not a huge problem, right?
Five minutes versus 10 or something.
So as a software developer, I also had to upgrade the functionality of our blog.
And one thing that we get now is we get the ability to preview posts in the actual environment.
So there's a YAML file in the repository, which is the index of all the posts, including
summaries and things like that.
And there's a published flag on there and published blog posts go to the live site and
all blog posts go to the staging site.
So we can publish the entire thing, check it over, have it live on staging.
Both of us can be happy with it.
And then that final pull request is simply changing the published flag from false to
true.
Yeah.
Yeah.
Even just locally previewing the thing, right?
You know, we can just run the server locally.
That's much easier than having to spin up that live server as I did in VS Code in times
past.
Yeah, that sounds great.
The only other thing that was a concern, I think it will be okay, but we should probably
just have a look when we go through the pull request.
Certainly it's okay locally is it's no longer a static site.
So the old site was a published site which runs and generates HTML that gets uploaded
and no server code gets executed during blog visits.
And of course, this is a dynamic site based on Vapor and all the rest of it.
And so one thing that my initial attempt at creating this was to get the summary out of
each file on disk, but to create the index page that was then opening up as many blog
post files as we had on the system, which of course is already potentially a performance
issue, but will only get worse as we publish more.
So the index now is driven off one YAML file, and then it only opens the actual blog post
file when you click into the page.
But there is an additional kind of process that's happening when people view those blog
posts, but I don't think it will have any kind of performance impact at all really.
Shall we briefly talk about our production issues we had last week?
Sure.
And how it was all my fault.
This was a joint effort because I laid the mine and you stepped on it.
Yeah, okay.
That's fair.
That's fair.
So, and as I said in our chat, that's why we have pull requests, right?
And have reviews.
It's one person opens up the pull request, the other reviews, and if something goes bad,
yeah, both people were involved in getting that live.
So that's the way it goes.
So just very briefly, what happened?
We had some, yeah, I mean, sort of downtime.
We had a crash in production, which led to our system sometimes showing 500s in Cloudflare
and timing out.
And crashes have been really rare, actually.
We've been blessed by very few crashes, and that's really thanks to Swift's focus on safety.
And then of course, the first real issue we have with crashes is when we opt out of the
safety mechanisms, right?
Because what happened is we triggered a force unwrap where we had a try with a bang because
we can't crash here.
And the reason was, I'm just going to call it reason A, you know, there wasn't even a
comment at the place where that force unwrap is, you know, we can't force unwrap here because
of reason A.
Famous last words.
Of course, what happens is your program says, well, I'll just make you crash because of
reason B then.
[LAUGHTER]
Which is a reason you didn't consider.
And that's what happened here.
It's just a great example where your exemptions hold for a very, very long time until they
don't anymore.
And a completely different thing blows up and then, you know, just goes through all
the layers and nukes the service.
What I really like is we have a-- if we consider this a problem that needs fixing, we have
actually have a very easy way of finding all the places where we've been doing this, right?
Like Swift is very nice in that you have to explicitly force this issue.
So if we just search for try bang in the code base, we'd find all the places where we're
doing this or similar things.
We would have an easy time auditing where we're using unsafe mechanisms and then review
if our assumptions still hold there.
So that's a really nice thing about it.
We explicitly force it.
And when I say we, it was me who wrote that try bang and made the assumption that reason
A holds.
And reason A still holds.
It's just that there's also reason B, which I wasn't aware of at the time I wrote this.
And so that's really the main story here that sometimes your assumptions change.
And yeah, that's how stuff goes wrong, right?
Where this maybe ties into future Swift changes is that the reason this blew up is that the
system is throwing under the hood.
And I thought there's only one way it can throw, but there's actually a different way
it can throw as well.
I was expecting database errors due to a join failing to be the source of throws.
And they can't happen because of the query we're running.
They can't really throw and they never have.
The problem is the other issue that can happen is that the payload that's being decoded can
also have a decoding error.
And that I did not consider at the time.
And if you've been following Swift evolution, you may have seen that there's a proposal
that's been accepted, which is typed throws.
Right now, if you have throws, they're really just this error protocol and they're not typed
in any way.
So you can't really make very strong assumptions about what's throwing.
Like I looked at, there's a call that's try and all I know, I'm going to get an error
back and I can't really do much with it.
With type throws, the underlying API could actually throw an error that is strongly typed,
not just that error protocol, but really a, it could be, for instance, an enum that enumerates
all the different error cases that happen.
And if that had been the case, I'd have been alerted to all the different ways in which
this can crash.
And then I'd have seen, okay, this isn't just a database thing that might go wrong.
Decoding might also go wrong.
Now, I don't think APIs will actually adopt it in this case because that's a huge thing
to do.
And this is more, I think type throws in the motivation for the pitch has been more about
very, very narrow use cases of this.
You'd use this where you have a subsystem that really has only a handful of different
error states that it's throwing where you really want to be sure that you gather all
that.
This call that I made has just way too many different things that might go wrong.
Even if you just consider database things, there's just too many things that might come
out of a database, especially because it's even different database technologies that
could be under the hood, right?
We're using Postgres, but other adopters of the API might be using SQLite and MySQL.
So it would be really hard to enumerate all the error cases there.
But I really wanted to raise this, that there are mechanisms in the future that might be
helpful to address this problem.
If you have a domain that has a very narrow set of errors that might happen, that it might
really help make your decisions whether it's safe to force unwrap, because when you see
it's an enum with four cases and you can ensure that those four cases are excluded or handled
elsewhere, it will give you more confidence when you do the try bang.
And I certainly shouldn't have looking at the result, but it's an interesting thing
we saw.
Yeah.
Whenever you find yourself writing that comment, "This can't crash," it sets off a chain
of events that will eventually lead to a late night.
Yeah.
Always bites you in the end.
But the good news is we are back up and running.
There was only a very, I don't know whether there was any actual 100% downtime.
Certainly the site was slow for a little while and there were timeouts, but I don't think
the site ever completely went offline because of it.
No, I don't think so.
Because what happened is that only a handful of pages actually led to the crash.
So people would have to visit those pages.
And then when that happened, a node was out for a minute.
And the problem, the reason it was out for a minute is a reason that we're following
up on.
That's actually not our fault.
Backtracing, unfortunately at the moment, is taking very long to render the backtrace.
And that's a new change in 5.9.2.
Previously, we actually would have crashed really quickly and probably people wouldn't
have had issues with the site being down, except for those pages explicitly.
The problem we actually incurred a little more, we actually hit timeouts was because
of the backtracing taking so much time and locking out nodes, which was a bit unfortunate.
And compounding with our self-inflicted issue.
Lots to learn from.
Right.
Do we have any other news or shall we do some packages?
I think it's package time.
Why don't I kick us off this week?
And I'll kick us off with a package called Vortex from Paul Hudson.
So Vortex is, well, let's take the description direct from the readme.
"Vortex is a powerful, high-performance particle system for SwiftUI, allowing you to create
beautiful effects such as fire, rain, smoke, and snow in only a few lines of code."
Now that's written like a true marketing professional, Paul.
I feel the desire to fill my apps with particle effects after that.
But it's actually looking great.
So it uses, you can add a Vortex effect to any kind of SwiftUI view.
So you can take, for example, a circle or a rectangle or something like that, or presumably
even something like a text box or a label or something like that, and add particle effects
to it defined by rain, fireworks, fireflies, magic, smoke, that kind of stuff.
This is probably not the kind of thing that you're going to use every single day.
But there are genuine uses for a package like this in iOS and macOS apps.
The most common one is whenever the person using your application has just completed
some kind of positive event, whether that's successfully doing the task that the app
was designed to do, or whether it was purchasing your upgrade to an in-app purchase or something
like that.
I've quite often seen people throw up a load of confetti on the view and have it rain down.
And I can imagine that you could use particle effects of all sorts.
In fact, there is a confetti effect in this as well.
But again, as you'd expect from Paul, it's a wonderfully written readme file, lots of
example code, and I thought it was worth highlighting.
Nice.
Are there some examples?
Can you preview what the package offers?
Sure.
I mean, there are animated GIFs on the readme file.
That's probably the best way to get a sense of what it does.
Right.
Nice.
And in fact, it looks like there is a demo.
In fact, it says the repository contains a cross-platform sample project demonstrating
all the presets.
And I do believe you can actually make your own particles too, if you'd like to.
Nice.
If the default confetti is not confetti-like enough, then you can make your own confetti.
Custom confetti.
Yeah, I saw this flyby, but I hadn't actually looked at it.
The iOS stuff, I expect you to pick those up.
Even though it's been a while since I wrote an iOS app, but I think I still have more
interest in it than you.
Well, there's this newsletter, right?
What's the title?
I don't recall.
I really messed up with several things when I named that newsletter.
I didn't think it would still be going 13 years later.
Right.
My first package is called Language Detector by Ali Sheikhizadeh and Hadi Shargi.
And this is an interesting package.
It's a small package, 400 kilobytes.
I looked it up because I couldn't believe it's that small.
And it offers language detection for 110 languages, according to the README.
I didn't actually count.
I trust that metric.
But it's a long list.
And I was really curious how that could work without either making online requests to
a service, it doesn't, or embedding some kind of dictionary language model.
And that I would have expected to be quite large, or at least larger than 400k.
So I've poked around a bit.
And it wasn't hard because it's not a big package.
But what it's doing under the hood, from what I understand, is doing frequency analysis
on letters and syllables.
So it just has small dictionaries in there with letters and syllables and then floats
against them, which I presume are frequencies in strings.
And that's why this whole thing is rather small, because these dictionaries are then
small.
I was curious how well that works.
So I took a couple of paragraphs from some European newspapers.
And it works.
So in each case, and I tried the big ones, English, obviously, German, French, Spanish.
And Italian, I think, as well.
And it worked for all those.
However, there's also, this spits out not just a single language, but like a little
dictionary of language and then a number.
And it's not documented, but I'm pretty sure the number is the confidence.
And that was, they were quite close together.
Sometimes maybe a bit too close for confidence if you really need this to be 100%.
But I think it's a great package if you want to, for instance, you know, you have a post,
imagine you have a Mastodon client and Mastodon allows you to set the language you're posting
in.
And that might be something you toss in there where you give, you pre-configure the selection.
You know, it's a low cost thing to do.
Even if it's wrong, it's not terrible.
And it might be a good starting point.
It might get lots of guesses right.
So I think if your goal is to get a good hit rate on your guesses, but you don't need 100%,
and you don't need, you know, don't want to ship a huge library of stuff, I think that's
a great package to try.
And give this a spin.
- And just a nice, it's always nice to prove that you don't always need AI, right?
- Exactly.
Yeah, that's why I was really curious if it's something like that.
I mean, obviously, you know, there's lots of quality in your estimates you can gain
by throwing more at it, but sometimes you don't need it, right?
The quick thing, even though you, there's a trade-off, right?
You have a lower footprint and faster response, immediate thing.
For, you know, maybe just 80% hit rate or something like that.
I don't know what it actually is, but it's certainly worth trying and giving it a look.
- That's great.
Sounds interesting.
My next package is by Kevin Mullins, and it's a package called Grace Language.
And as I was preparing for today's podcast and thinking about how to talk about the
engineering of a blog system that I did yesterday,
this rings a bell as well in that if you want to allow plugins or some kind of scripting
inside your iOS language, your iOS or Mac application, what's the first thing you do
is you design your own language first, right?
- Right after the editor, yep.
- I'm not sure, yeah, exactly.
I'm not sure that that's how this came about, but it is a new language called Grace,
and it is apparently a Turing-complete scripting language written in Swift that can be used
in applications that are then written in Swift.
So it is, the language itself has enumerations and structs and functions and things like that.
I didn't spot anything in the readme about it being object-orientated.
There's certainly no definitions of classes or anything like that.
It may just be a kind of, what do they call them, procedural language.
But certainly the syntax looks nice enough, and you can very easily bring up a Grace runtime
inside a Swift environment and run scripts or other code that's been written in this Grace
language.
So it's the kind of thing, I know a lot of applications, when they look for a scripting
language like this, I think Lua is quite popular, isn't it?
- Yeah, you see that pop up a lot.
I think a lot of that is due to our World of Warcraft using it as its scripting language.
- It did, yeah.
I believe it still does, yeah.
- Yeah, well, yeah, certainly, yeah.
Interesting.
So are there any interfaces?
How would you use that?
Is it just for computations or can it actually interface into the system back, you know,
like calling, you know, dialogues or shortcuts or stuff like that?
- That is a really great question.
Really, really great question.
- Here we go.
- I don't know.
Let me have a quick look.
In fact, I was just scrolling up and down to see if I could see that.
I can't.
Although maybe I can.
It keeps, a lot of the examples call app print, which I wonder if that's calling back to the
host language.
I would recommend that if this is interesting to you, that you go to the readme and give
it a thorough read, which is something I didn't do.
- Nice.
Nice.
Right, my second pick is called Versioned Codable by Jonathan Rothwell.
And this is a really nice package, which one I probably would use if I had a use case or
might even have one in the future.
So this is a pack to deal with versioning of codable types.
And we all know that problem, right?
We've defined a codable type in our application and we've saved some data.
And then we want to change that codable type.
And we have data on disk or worse, some elsewhere, users have it.
There are other services that use it and we are kind of stuck, right?
If we change the type, we can't decode the old data.
We want to change it because that's just the thing you want to do.
You have no requirements, stuff like that.
What do you actually do?
And if you've worked with database systems, you've likely come across this concept there,
which is called migrations, where for every change in data format, you have a system that
migrates your data and then allows you to interface with it and write it and read it again.
You know, like if there's a new field, if you have a field change or you remove a field,
you have these migrations where you migrate your data over.
And versioned codable does something similar for your codable types.
And it works the way that each type, each version of your type is represented by a codable struct,
just a plain old codable struct.
And then you adopt a versioned codable protocol.
And what this does, you declare what the previous version is, and then you define an initializer to
instantiate that new type from the old type.
And that then allows the system to lift up.
If it encounters an older version, it goes through the chain until it arrives at the
latest version or whichever version you actually want to decode.
You don't need to, you can decode any version along the chain.
But what you effectively set up is a sort of linked list of versions and whichever version
you have, you know, goes into the chain and then, you know, you just keep on migrating
them forward until you end up at the place where you want to be.
It's really nice, a very simple interface, very obvious how you would use it.
A nice readme and documentation to explain how that works.
It also works in a playground, so you can just fiddle around with it there, see how that works.
And a really nice thing that the author, Jonathan, has laid out that there's a bit of boilerplate
there.
It's not a huge amount, but I think he's planning to use macros to even do away with some of
that.
So this looks like a really nice package if you have the need for a versioning of codable
types.
>> That sounds great.
>> I give it a look.
Version Codable by Jonathan Rothwell.
>> Very good.
So I think that's probably enough packages for today.
>> I think it is, yeah.
>> So yet again, we come to the end of another episode and we'll be back in a couple of weeks
with some more news, hopefully less news about crashing and less news about writing our own
blog engines and more news about the wonderful other projects that we're going to embark on
this year instead.
>> Absolutely enough with the crashes.
See you in two weeks.
Bye bye.
>> Exactly.
See you then.
Bye bye.