32: Which of your dependencies are load-bearing?
We actually got some follow up to talk about. Because we know nothing Jon Snow.
Remember we talked about extending our package usage popover last time.
I do. We were going to add a product to it and we, even better than that, we followed through
and actually did add a product clause to that use this package window. So tell me what went wrong, Sven.
Well, we talked and we even ranted about package names and all that, remember?
With the Swift prefix?
Yeah, how people should name their repository one way and then use the name inside the package as
something nice, you know, without the Swift prefix and stuff.
Well, it turns out the product clause that you need to put into your dependencies, you know,
when you have a, have a target depend on a product there, you specify the product name that you use
and you specify something called package colon is the, is the label for the, um, for the product,
thing, I said, this is the package name.
It isn't, it isn't.
We use the package name in the clause that we construct there, but it actually,
that, that actually produces a wrong product clause because what actually
needs to go in there is I think what Swift PM internally calls the package
identifier, and this is derived from the repository.
So I tried out a package which had a package name auto merge, but its repository is called
Swift-automurge. And what needs to be in that product clause is Swift-automurge.
I really, really hope that once we move to package registries, which will really have proper
package identifiers, and I think there's a scheme proposed where you have like an owner slash
package sort of scheme, which obviously then allows you to disambiguate in case,
probably common case that there will be overlap in package names. Once that's there,
that'll probably allow for better package names and still avoid clashes in names.
But currently what seems to be happening, and I vaguely recall seeing this, is that
Swift PM uses an identifier based on the repository name internally as a package ID,
and that's the thing you need to specify. And I guess that's perhaps why it's called just
"package colon" and not "package name", because it's not really the name but the identifier.
- So hold on, it's coming from the Git repository, nothing to do with the package?
- I think so. I can't think of another place where...
- Okay, wow.
As actually not Swift-automurge, it's automerge-swift is the name of the
repository and what Swift PM says needs to be.
So I tried this with just automerge as the package label there and Swift PM
package resolve says the only valid package it knows about is automerge-swift.
And the only place, the only other name, the manifest doesn't talk about
AutoMerge-Swift, if I recall correctly.
So the only other thing that has that name is the repository.
- So I'm learning about this for the first time
live on the podcast,
because I knew that there was the issue,
because you opened an issue this morning.
But this is the first I've heard of the solution.
And I think it says quite a lot that,
I mean, I would say both you and I
have a reasonably good understanding
of Swift package manager at this point,
after working on the package index for three years,
and if we get it wrong, it's too confusing.
- Well, maybe not.
(both laughing)
- So I guess are we gonna have to pass,
I suppose we have the repository name already
in our database, so this I think is fixable, isn't it?
- It is fixable, I wonder if we should,
so I'd love for the proper fix to be,
I know, so for instance, if you look in package resolved,
Um, the JSON file that gets, gets written out after you run Swift package resolve.
In there, the struct, if I recall correctly has an identifier.
So it says four packages, it has the URL and in the version two of that struct,
um, there is also an identifier.
And I, I think that's the thing I need to confirm this and I would rather try and
and grab it from there or some official source than try and guess it from the
repository name, you know, because that might change and then we have subtle breakage.
I'd really like, because also this will, this will certainly change once we move to registries,
because then I think the package format will use proper package identifiers and not, you know,
these names that we're guessing. And we should really try and have some canonical source for
what's actually used to identify what package you're looking at. And I think that'll solve
everything in the end. And I truly hope the thing that we arrive at there isn't a Swift-Dash thing,
but just a proper name that is disambiguated across projects and stuff, but is still
nice and readable and has maybe a subcomponent or just a separate name that is descriptive and
can be ambiguous because it's not the one used for identity matching, but can be the one that's
displayed elsewhere. But this thing we thought it was isn't that.
The downside is that we've already shipped and deployed the wrong version, but that's okay,
we can fix it and get it working shortly. Yeah, I think it's not a common problem.
The vast majority of the packages actually have those aligned anyway.
Of course. Yes.
It's probably we're punishing the ones that actually do the right thing, sort of.
and we should absolutely fix it. No good deed goes unpunished. That's the way it
is isn't it? There is another piece of news that we have this week which is we
shipped a new feature to visualize the number of macros that a package includes.
So we've had this data in the database for a little while now and a few weeks
ago we shipped support for searching on whether a package has macro targets and
now we have a new bullet point on the metadata section in the package page
which shows you if it has any targets and if so how many targets it has and I
already found it useful today when I was looking through package recommendations
for the podcast and I looked at this one package and the name of this package
suggested to me that it might include a macro and I instantly opened the package
page and discovered that I was wrong and it didn't have a macro in it. But that was, you know,
that saved me a whole load of digging through the package for manually
trying to figure out that information. It was nice to be able to see that
right there on the package page. So nice, yeah. That's another small but
It's an important improvement.
- Nice to have that on there and not just in the search.
- It was a little bit of a struggle to come up with an icon
to represent the concept of a macro.
The closest I could get was macro photography.
So it looks like a shutter in a camera,
but I am aware that that is stretching it a little bit.
- Yeah, it's a bit very obvious icon I'd say.
- You try and represent macro better.
I don't know maybe a puzzle piece now
that I think of it. Okay with what what
connection? Well it sort of expands and
is a piece of a larger puzzle. That makes
perfect sense doesn't it? I mean in my
head that is. I'm very happy with a
camera shutter yeah. All right well I'm too late now anyway.
Right in in other news there's something worth mentioning and that is GitHub added
CodeQL support recently and there was a really nice introductory post by Tim Condon on the
Swift forums. I saw it yeah. And what this does is it allows you to add code quality checks
that run automatically on pull requests and your main branch.
So this is something, it's really simple, I just added this
this morning to one of our repositories to try it out.
It's really just a small YAML snippet that you put into a new
workflow file in your .github/workflows directory.
And then it runs a check automatically
and I guess it checks for specific quality metrics in Swift code, common bugs and stuff like that.
And the new thing is obviously that it now supports Swift. This has been around, I think,
for other languages for quite a while. And it's new that this is supporting Swift now.
As I said, we added this to a semantic version, one of our packages.
And we'll also add a link in the show notes what this looks like. There's a little overview page
for the most recent scan to show that it's working and it's done its job and
hopefully not found anything. So that's quite nice. And another thing that GitHub
added recently is in Dependabot there's now support for Swift. Now Dependabot
also is a feature that has been around for a while for other languages which is
a tool that checks for outdated dependencies in your package.
And so if you add this to your repository, it'll go through.
And now it's supporting Swift.
It'll check if there are any Swift dependencies that are outdated
that should be updated.
We've actually had this for a while now with a different package,
and that's a GitHub action by Mako Eidinger.
It's called Swift Package Dependencies Checker,
which is also really nice.
And we'll actually keep using that tool because this tool is, uh, supports the
latest Swift version.
Now the GitHub, the Penderbot feature only supports Swift 5.9, but with our
main repository, we're using it, we're already on the Swift 5.9 beta, so we
can't actually use it there yet.
So Marco's tool is, or action is still very useful for us and is also a really
nice thing to get the same feature effectively.
So what this does, it'll open a pull request on your repository when there
are changes in your dependencies.
You can review those and then just merge it if you're happy and have
one to all your dependencies to move up to the latest version.
Yeah, it's great.
And, um, I think, I mean, there was macro script is, is really good.
Um, and we've been using it happily for months now, if not maybe a year,
something like that a long time anyway.
Um, but obviously that takes, that takes investigation. And first of all,
you have to have the, the,
the idea to research whether anyone's figured out a way to do this.
And then one thing that's really important about some company like
GitHub taking a hold of this problem is that it
raises this issue into people's kind of into the
front of people's minds. You know, there'll be a lot of press around, um,
blog posts and people talking about it and us talking about it on the
podcast and other podcasts talking about it and that kind of thing.
And half of the advantage of that is just letting people know, "Oh, if you haven't yet
done this, then this is a great thing to think about for your projects or repositories."
- Yeah, and in particular, because the onboarding is so easy, there's a couple of things you can
just do with a click of a button. And the most extensive dependency check, because it can actually
do a dependency check also beyond your major version. So it can actually alert you to a new
latest major version that you're actually not opting into. And that requires additional
configuration. But all the basic stuff is actually just a click of a button. So it's so easy to
to configure that there's really no reason not to do it.
Um, the only slight downside is that GitHub doesn't have a great history,
um, supporting the latest, um, beta versions of stuff, you know, like macros
version in particular, that runners are always a bit behind and the Swift version.
I, it doesn't support it right now, but it's also a very new feature.
So we can't judge it based on that.
Um, we'll have to see how that goes, but I suspect if you're.
tracking the latest beta version of Swift, that might not be the tool for you then in that case.
- Yeah. Although there's another way to look at that, which is that now this tool supports Swift
and more and more people would be relying on this tool. I don't think they'll go into beta versions
just yet, but it might increase the urgency of upgrading to latest release versions because
If they don't, then this tool will stop working for a certain amount of projects, and maybe that
will slightly up the priority of those upgrades a little bit. I think there's one other thing worth
mentioning here, which is part of this feature I think is actually switched on by default,
and you have to opt out rather than opting in. And that is that if there is a security
CVE raised against any Swift package, it will depend upon will automatically, without you opting
into anything, it will automatically alert you to that problem. And you can then opt in as well to
have it raise a pull request to increase the version of just that one package
outside of the global dependency update thing. Oh, that's really nice. I wasn't aware of that.
That's really cool. Yes. This whole automatic tracking and reporting is just so great because
it's the thing, if you don't think about that and set up the schedules for that, it's really easy to
just miss out on all of this. And you might have an idea to sometimes run Swift package update and
absorb that, but you know, who does that manually? It's just something you easily forget. Yeah.
Right. Another thing we might want to talk about is an upcoming feature.
I mean, not upcoming in the sense of next week or the week after, but it's something that we've been
working on for quite a while. And it got sort of pulled to the forefront again, because as part of
Dependabot, there is something in GitHub that will obviously deal with dependencies. And I think
there's also a way to see package dependencies of Swift projects. I haven't actually seen the UI,
but I saw some mention of it. I need to go back and check if it's actually in the
Git UI, but it reminded me that we had started work a while back on displaying dependencies
on the package page in the Swift package index. Now we do something already. We do show the total
dependency count of a package on the package page. And all of this is based on package resolved,
which is the file that SwiftPM writes out when it does the package resolution.
Now this dependency count is nice. It is useful, but it's also, it captures all dependencies.
that is both the transient dependencies as well as the test dependencies. And
that might not always be the thing you're looking for. And we certainly want to extend this. And
we spent some time quite a while ago to look into how to extend this, in particular to
break out the test targets so we can actually display these separately. I call them product
dependencies, which are the dependencies that your products, your package products depend on,
and the test dependencies separately, and in particular to make those dependencies navigatable
on the package page. And I think it's just worth mentioning at this point how this problem is
manifesting itself with the current implementation that we have. So if you look at a package at the
moment, you might see this package has four package dependencies. And let's say, for example,
that package uses one dependency in the actual package, and then QUIC and Nimble and maybe
another test dependency to run their tests. Seeing on a package page, this package has
four dependencies might put somebody in a frame of mind of like, oh, actually, that's quite a
quite a lot of dependencies to have for what might be a small package, but actually three of them are
only there to run the tests, which I mean, in my opinion, test dependencies are much less important
when I'm choosing a potential dependency for my project than if it were a product dependency.
And also, it's also not clear on our webpage
whether those dependencies are direct or transient.
And I think if I saw four dependencies
or three dependencies or two,
I'd assume that's two top level,
but we have no current way of showing that information.
- Yeah, and it'll be really nice
if the top level dependencies were shown, right?
And you could click through
and then if there are actually a package in the index,
it'll land on that package page.
would be really nice to have that graph traversable.
You know, obviously, if if it's not in the index, which is unlikely
because we actually add them automatically,
if we find we have a nightly job that goes through
and if a package is referenced by another package that's in the index,
it's then added to the index in the next day.
So we should actually have a fully onboarded graph of packages.
But it would be really nice to have those exposed
and make them navigatable.
So yeah, that's certainly something we want to do.
And what we did first is look at package resolve
because that's really easy to do.
And Swift PM does all the heavy lifting
of actually accounting for all those dependencies.
But the problem is--
- Actually doing the resolving.
- Yeah, that's the problem.
And there is nothing in package resolve
that will tell you afterwards what are direct dependencies,
What are transit dependencies?
What are test dependencies?
It's just a flat list of dependencies.
And that's why we have that fixed number and we can't really separate those out.
There is a way of doing that.
That's not too crazy that we spent some time, um, figuring out how to do, and,
and this is the approach we'll take.
Um, but it's maybe worth thinking of the main queries where we're
wanting to support with this.
Um, and obviously all of this is up for discussion and we actually have an issue
where we currently tracking our thoughts around this, which we linked to in the
show notes.
Um, and I think, I mean, you alluded to this, the product dependencies are really
where the meat of the matter is because those are the ones that go into your app
or your service, whatever it is.
Those are the ones that partake in your, in your, um, artifact that you're shipping.
So those are the ones that going to be impacted by CVs and the like.
Or just source code breakage, right?
If you want to assess ahead of time, how exposed am I to potential API changes
and having to deal with them, the lower the number of packages, the less likely that is.
So that's why that's important.
And this also assumes that in a pinch, right, if there's breakage due to something in test
dependencies, you can ignore those, right? If your test dependencies depend on a package
that has a change so that you can't run your tests and you really need to get out a hot fix,
I think you're going to have an argument and say, right, okay, we need to fix this. We can do some
manual testing, we get this out, and then we deal with the test dependency after the fact. That's
probably something you can get away with. If that's a product dependency, you can't.
100%.
So that's why that distinction is certainly important.
But test dependencies are still important because there's this other thing that comes up
again and again, and that's being referred to as the software bill of materials.
And that's effectively your complete attack surface to supply chain attacks.
and test dependencies do play a role there because you run stuff. You run your tests,
and anything you do in CI or locally, anything you run and any source code that goes into
impact what you run there is open to any malicious package messing with what you're running and where
you're running it. A while back, way back, there was a compromised Xcode version that got shipped
and or got, you know, people were tricked into downloading it and that impacted how you ran your
stuff. And then downstream from there are all sorts of problems, you know, like secrets being
leaked because of stuff like that. So you still want to know what your total surface is, you know,
what code are you actually pulling in across your whole package, but there's a bit of a difference
in, in importance, I guess, or, and because these supply chain chain attacks are, are
probably not targeted at an indie developer or if, if it is, you know, you're probably.
You're probably not going to be picked on it.
They're going to pick the, the big targets, the important targets.
Um, but it's certainly a good thing to have exposed and to be able to see ahead of time
what the list of packages really is, what that bill of materials really is.
And maybe the last thing that's interesting is usage tracking.
And that's how many packages depend on this package P that you're looking at.
And while that's an interesting metric, that's probably one that we can never
really produce in a useful sense, because we only see open source packages.
So any usage we would ever see in these metrics is open source
packages using this open source package.
And given that we currently track 6,000 packages and there's like, it's
millions of apps out there, right?
This is going to be dwarfed.
Like it's the number of, of actually packages using a package like alarmofire.
It's not the package that we have in index that use alarmofire that are
the actual clients of alarmofire.
The clients of alarmofire are all the apps in the app store that actually
embed that library and we have no usage stats on those.
So that is probably not really even a useful thing
to try and expose.
- Yeah, it's tragic in a way because we do have,
well, we will have a really nice set of data,
but I would say that unless we come up with a way
for people who build apps to anonymously report
what packages they are depending on in their app,
which we could do. And we don't need to go into how we could do that, but we could do that.
But I also think that, you know, even if we went down that route, there's so much work to do to get
people to adopt that, that I'm not sure we could ever trust that data. And I think it's almost a
little bit of a tragedy that we'll have a subset of this, but we won't really ever be able to do
anything useful with it.
Yeah, I think it might be really nice. And maybe that's an option if a package registry had a way
of reporting that back to us or some service, because I think there's value in that for
you, even for the clients of Alarm or Fire to report that back.
Because then on the way back, that could be reporting of CVEs.
Imagine someone is, for instance, using Swift Neo and there could be just like Dependabot,
it could be a service maybe based on the package index in combination with the registry to
report back to application authors that there's something wrong and notify them
that there's a CVE against a package that they're using.
So that might be a nice avenue to incentivize people to opt in if it's an
opt in process to this kind of reporting.
And that data is in many ways much better than a lot of the data that language,
other language indexes use.
So for example, a lot of dependency indexes
for other languages use downloads as a metric
of how popular something is.
So whenever a package is grabbed by the package manager,
they'll take up a count on the number of downloads.
And that's certainly an indicator,
but there's enough downloads
that someone trying out a package
or just testing something.
Whereas if you actually have what packages
are actually in use at build time,
that's really different information.
And I think it's probably a better indicator,
but we've got such a long road to go down
for that to be anything like useful.
And I think step one is exactly what we're planning
to do here, which is give people some information
about the dependencies of the packages
that they are considering using themselves
and not to worry about the bigger picture.
- Yeah, and I'm hopeful that we can break this down further
because it's quite a large piece.
I went through my notes this morning
to sort of recap where we left it.
And this is going to be quite complicated.
And hopefully there's some intermediate things
that we can release to make that incrementally more useful
than it is now with the total count.
- Even if it's just the case of bringing the data
in bit by bit or adding the extra bits of analysis
on the data bit by bit before we expose anything
to the user interface.
So yeah, I think it would be good to chip away at this
in smaller chunks.
It's always better to approach things that way.
- Yeah, definitely.
- Right, we've actually,
we've whitted on quite extensively today.
Let's get into some package recommendations.
Do you wanna give us the first one?
- My first one is called DataKit by Paul Kraft,
Paul Kraft, he's German, so I'm confident in the pronunciation of the name.
That's not what I got from the way you said that.
I didn't get any confidence at all.
Damn.
DataKit is a really great package.
I loved, I loved seeing this.
Um, it's a great package when you're working with custom binary data formats.
And this sort of brought me back to a time several years ago when I had to
decode a proprietary proprietary data format.
Um, and even way back further in the physics days, where we're losing, using
lots of proprietary custom data formats, because it really, every bit even counted
at the time, and this can be really fiddly, but what this package does, it
gives you a, um, result builder based DSL where you can actually specify this.
It's really nice.
It sort of looks like Swift UI layout, but for your data, you can define static data
blocks, like certain byte patterns that you want as markers.
You can then specify your values, properties, do conversions where needed.
So by values, properties, I mean, you know, like data types.
And obviously specify quite in detail ways, the bit size of them.
Use conversions where needed.
really nice. The reading and writing can be driven by different conformers to a read format
and a write format protocol. That's if you have to do different things or if you only implement a read
of a format, for instance, or you can do it jointly by conforming to a format. It's a bit like
codable, you know, that has a encodable and a decodable form protocol that you conform to.
And it also has a CRC checksum support component so you can tack this on and then
I guess in some way ensure that what you've received and decoded is actually
came across the wire and is intact still. Really nice. This whole thing works in a playground so
you can use our feature to try in a playground which I always love calling out because that's
how I actually play with packages and look at them and you can and that I would have found really
really useful working and trying to load a file, stick this in and then piece by piece try and
parse a file back out. So really nice package. DataKit by Paul Kraft. How was that for the
pronunciation, Dave? Yes, much better, much more confident, absolutely. My first package is a
package that we don't use directly, but we do use the underlying technology behind it.
So the package is called SwiftWhisper by Aaron Taylor. And it is a wrapper around a C++ library
that interacts with the Whisper AI model from, I believe it's OpenAI that produces the Whisper
model. And Whisper takes audio files and will transcribe them with quite unbelievable accuracy.
It is a remarkable library. So we use it to transcribe all of these podcasts. We run it
through an application called MacWhisper by Jordi Bruin. There's also an app called Ico, which I
which I believe is by Sindre Sohus.
And both of those use the whisper model
to take in an MP3 file or a web file
and produce a transcript.
And I mean, I'll see how it does with the,
with your pronunciation of the previous author's name
this time, but it does actually get author names
like remarkably accurately transcribed.
It's an amazing bit of software.
And so this package is a way for you to interact
with that model from a Swift application.
It doesn't come with the models included,
but it does include a link where you can download
pre-trained models, 'cause obviously the model
is a huge part of that dependency.
But yeah, it seems like a really easy way
to get either offline or even potentially
real-time translation, transcription, sorry,
into an application that you're looking at.
And the nice thing about it is that these models
can be shipped along with your app.
So it's not the kind of thing
that requires an online connection.
- Nice, yeah, I'm really surprised
about the quality of these tools
and how quickly that evolved.
Cause I recall that being quite difficult and often, you know, especially with
technical terms and names and stuff, this, this is so amazing that this actually works.
I mean, there's still cases where this doesn't work correctly, but you can see
with, with, you know, bigger models that it'll, it'll get there.
And I, even, even humans fail at this at times, right?
You misunderstand something or you have a different term in mind and are
confused about what it is.
So it's not, not surprising that this goes wrong sometimes.
And we've talked about this on the podcast in the past and this idea of,
um,
uses for AI that don't involve the AI having to come up with kind of original
thought or original data or knowledge based answers and things like that.
And this is a perfect example of that. Yes,
it might not get every single bit of transcription correct,
but it's never going to just start hallucinating or at least in our experience
it doesn't, it doesn't hallucinate. It sometimes,
It sometimes makes mistakes, but it never hallucinates.
And it's because it's that problem domain
is very well suited to this kind of AI.
- Well, sticking with the theme,
my second pick is actually very similar.
It's called Cleverbird by BT Franklin.
And it's an open API, no, it's an open AI API wrapper.
And I actually mistyped this in my notes
because I always mix these up.
Open AI API wrapper.
And it's actually the package we're using in one of our packages to generate package
descriptions. So this is a little proof of concept kind of thing that we're doing.
And I had a really interesting use case this week for these package descriptions.
I actually used our tool to generate a package description for a package
called a ZuKeyKanaKanjiConverter.
And this is a package, we'll have a link in the show notes that has a readme in Japanese.
And because the GitHub page is in English and the readme is in Japanese, the Google's page,
webpage translation or Safari's webpage translation doesn't work or it's not offered as an option.
So I couldn't really tell what this package really does,
and I wasn't sure if I might want to mention it.
So I ran this tool on this package,
and it actually gave me an English description
of the package, what it does,
and it does appear to make sense.
So that's really nice,
how these tools open up these things.
Not only does it tell you what this page is about,
at the same time, it gives you a short summary.
So I think that's a really interesting use case
these open AI or general in general and AI tools?
Um, you may or may not know this, but, um, in the work that I did on the prompt for generating the
summaries, um, I actually looked into also translating and there are lots of different
options that you can kind of get out of, um, uh, of GPT with translating or not translating. You can,
you can and it understands your wishes to summarize something and also translate it at the
same time or summarize it and keep it in the same language and there's lots of different options.
Especially with the translation, you're straying into stuff where
potential hallucination could be quite dangerous because you might not know whether if it was
translating something, you might not know whether that translation was accurate or not. But certainly
in summaries it's often operating on a very good set of initial data. But certainly that
translation, I think that actually made it into the prompt that we ended up using
in the end that it should also translate it to English.
Yeah. I recall, didn't you test it with a Chinese package or something when you wrote the prompt?
Yes, we did with Chinese. I think we tested it with both Chinese and Japanese text.
Nice. So yeah, that's so the the OpenAI wrapper, API wrapper is called Cleverbird and it's by BT Franklin.
That's good. My second package today is called Stores and it's by Omar Albeek.
And Stores is a key value store to store code of all types, but the destination of that store is
is configurable. So with the same data layer, you can store your data in user defaults on the file
system, into core data, into the keychain, and you've got the same interface to all of the
storage no matter what ultimate destination you're using. Now, obviously we've got Swift data, which
which is new this year and in beta at the moment.
And from what I've seen so far, I really like Swift data.
And I think it removes a lot of why I hesitated
to always recommend core data,
which is there's quite a lot of initial setup
and you've got to think about,
you've got to think about your storage quite carefully
before you pick a core data.
Where sometimes a plist file on a file system
a JSON file and file system might do just as good a job,
depending on what kind of data
and how much data you're looking at.
And what I quite liked about this package is that
you can almost defer that decision.
So with the same interface to the data store,
you could start with file system store
and then potentially move up to a core data store later.
Of course you are tied in
and with any data storage package,
or in fact, any package that goes in
at the root of your application,
it's a much, what's the best way to say it?
It's a much heavier dependency to take on
than something that's right at the edges
where you could easily replace it.
Once you make a decision in your data store,
you've gotta be really sure
you wanna stick with that data store.
- Yeah, that's load-bearing.
(laughing)
- It is load-bearing.
That's exactly the way to describe it, yeah.
But I quite like the idea of it,
and it looks to be fairly mature.
It's only been around for 11 months,
but it's already had 12 releases, so that's a good sign.
And it's well-documented.
The documentation is hosted on the package index,
which we know that always gives people a leg up
into getting picked on this podcast.
(laughing)
So that's Storz.
Right, my third pick is the Swift composable architecture package by Pointfree.
And the reason I want to mention it this week, and I think because I think I mentioned it before,
is that they've now made their 1.0 release. So I think that's certainly worth talking about
briefly here. We should also mention that Pointfree are sponsors of Swift package index.
But all their packages are open source and free so you know you can get a lot out of them.
They really have great packages and they have excellent documentation so
you don't need to subscribe to point free to make use of it.
This is all available and really really high quality even before 1.0 release.
I've been using the composable architecture for I think at least three years now.
Now I'm not writing a whole lot of UI apps. I think I count like four small ones over the last
four years, but they're all TCA based because I, once I learned how that works, it really resonated
with me to the extent that I, I really feel like I can't write UI apps anymore. Well, actually I
didn't, I never really felt comfortable writing UI apps before because of the way I tend to write
code which is really test based.
So I really like to test stuff and UI code is often really hard to test.
And that's perhaps the strongest argument for TCA that I can think of, at least
personally for me, is that it makes UI apps so testable and therefore manageable.
Because the thing is you might bang out an app really quick without tests, but
Where it really pays off is in the maintenance.
If you have, you know, add more features, have more releases, the bigger your test
suite, the easier that still stays and remains updating your dependencies, that
sort of stuff, all that stuff really scales much better, is easier, more easily
done if you have lots of tests and TCI really makes that possible.
Um, they have this, um, unidirectional data flow where actions modify a state
in a store and that's really the only way to modify your store and your views are really
just displays of the store. And that concept really makes it for me like really natural
and easy to work with UI because it then becomes less magical. I always struggle with UI apps
because stuff seems to be happening magically. One change, little change over here in the
would suddenly make things happen on another end.
And I never really got quite comfortable with that.
And TCA, I think is the thing that really made that click for me.
That you can test all the logic in unit tests and then have snapshot tests,
for instance, for your UI views.
So, yeah, there you go.
TCA, the composable architecture 1.0
after a long time of being in pre-release by point three.
- I think it's also worth mentioning
with Composable Architecture that they've done a great job
with obviously documenting it through their video series,
of course, but also documenting it through
actual documentation.
And they've also put together one of those Doxy tutorials,
which is an extensive,
I think it's like a four hour potential length tutorial
or something like that that I saw
that, you know, putting together a tutorial like that takes time and effort. And it's great to see
that kind of effort going into an open source package like this. Yeah, the other thing I really
want to call out is, you might think, well, 1.0, I'm going to wait for 1.1. The way they've dealt
with version changes, even leading up to 1.0, I don't recall a time when there was a breakage.
They always had releases with deprecation warnings and then the most detailed adoption
documentation.
You're like, when you adopt the new version and you get deprecation warnings, you need
to do this to fix those.
Or, you know, if you jumped a few versions, you could see, all right, I need to do this
and this to fix my compile errors because you skipped over the deprecation version,
ended up on the new version.
It's been, I've picked up apps that I'd written
three years ago and went through,
and it has always been really, really hassle-free
to move along, and I'd say this is a safe library to adopt
if you're concerned about breaking changes.
It's really amazing the way they've dealt with this.
- Although to use your phrase before,
this is very much a load-bearing library.
- It is, yes.
You have to be, you have to buy into the concept.
This is not something you'll pick up in one evening, I guess, unless you're
perhaps comfortable or you know React Native, which is I think very similar.
Or I think Elm also has this unidirectional data flow concept.
It's certainly different.
It's quite, and it is an architecture.
It's like an honest architecture that you need to adopt in your app.
It's not something you should do lightly.
Having said that, I do believe it's something you can adopt partially.
So, um, this might be something to look into.
I do believe you can do this in, you know, in a, in a screen or two in your app and
I see how it goes and take it from there.
So you don't need to onboard your whole thing into this, but it's certainly easier
to get to start out with this in a, in a new app or a smaller app to, to see how it
goes and that goes to Dave's point that there's a really, really good tutorial and extensive
tutorial. So there's lots of stuff there to get started with it and see if that's something
for you.
That's great. My last package is not this week a cleverly or amusingly named package,
It is an amusing content to this package.
The package is brand new, five days old,
and it's called Swift NRC by Joe Hinkle.
And I'm not entirely sure,
I may be misrepresenting this package terribly
in saying that it's kind of a music content,
but it's the description of this package is,
Swift objects without reference counting.
Do you ever wish you could go back
to manual memory management and Swift
is the kind of language that just does not let you do that?
Well, Swift NRC is here to help.
It's effectively a package with a macro inside it,
which allows you to use the unsafe pointers of Swift
in a slightly more,
is they wrap up the unsafe pointers
to allow you to do your own memory management.
I don't think you should use this package.
I think this package demonstrates
some interesting things with macros.
I don't think we should go back
to manual memory management,
although there are potentially uses
that may be performance or something like that.
Although even then, I'd be really surprised
if going back to pre-arc days was ever a good idea.
But I did, it did make me smile.
It did make me, it's an interesting little package
and I thought it was worth a mention.
- Very nice.
- But please don't use it.
Right, and with that, I think we should call it,
and we will be back in two weeks
with more package recommendations
and potentially an update on dependencies
potentially a fixed version of our use this package popover. Great, see you in two weeks.
So until then I will see you in a couple of weeks. Bye bye. Bye.