Swift Package Indexing

What even is a recommendation? Join Dave and Sven as they talk about the tricky business of recommending, endorsing, or showcasing packages before diving into a review of dependencies in other package ecosystems, and how the Swift package ecosystem compares. Then we showcase some packages, as usual!

News
Packages

Creators & Guests

Host
Dave Verwer
Independent iOS developer, technical writer, author of @iOSDevWeekly, and creator of @SwiftPackages. He/him.
Host
Sven A. Schmidt
Physicist & techie. CERN alumnus. Co-creator @SwiftPackages. Hummingbird app: https://t.co/2S9Y4ln53I

What is Swift Package Indexing?

Join Dave and Sven, the creators of the Swift Package Index open-source project, as they talk about progress on the project and discuss a new set of community package recommendations every episode.

It's actually something we started to talk about on that failed recording, which is that the...

where it's come from is, as I've been working on this packages page update for Swift.org,

it's made me think a lot about how we pick and recommend and discuss packages. And there was

there was a bit in that failed recording where we talked about a package

and I ended up talking myself out of recommending it halfway through.

Well you talked yourself out of it, you immediately said you shouldn't be using it.

You didn't give yourself much of a chance to be honest.

And afterwards we were discussing the failed episode and you said it was a bit of a shame that that got lost

because it is actually an interesting thing. Like there's value in

talking about things that you wouldn't automatically... like a recommendation is a

funny thing because a recommendation it almost makes no sense because what might

fit my use case might not fit your use case and it might not fit everybody's

use case but there will be some people who find something in everything right?

So recommendations are a little odd in that way, but also there's value, I

think, in talking about things that you wouldn't necessarily use, and there's

still value in that. And it's something I've been thinking about,

like I say, over the last few weeks as I've been putting the final touches on

the packages page and that process that we're going to put in of people

suggesting packages to recommend and then having a kind of editorial

process of picking some packages to feature on Swift.org temporarily. And

that they shouldn't be pitched as like, "these are the best packages ever." It's

just, here are some packages. They may do interesting things.

They may do interesting things and not be for you. They may, you know, they may be

something that you can learn something from or get inspiration from or there's many many reasons

to look at a package. Yeah absolutely yeah yeah I agree and and you can learn something from

having a package discussed that is clearly not your use case but still it's well valuable in

knowing that's just not right for me it's too big for me it doesn't do it quite the way I would need

it it's you know it's too complex because of the yeah trade-offs it makes you know lots of things

are just trade-offs, right? There isn't the perfect package because the perfect package

is effectively almost, you know, often something you would have to write yourself because that's

the only way to guarantee it's actually tailored to your requirements. I mean...

>> Can I suggest Foundation? >> Yeah, but is that a package in the sense that, I mean,

obviously at some point it'll be a package in the... Although actually that's a great point,

because many people will argue Foundation isn't a good choice for what they're doing.

You know, they might be on resource constrained devices.

Many Linux folks say, "I don't want to pull Foundation in because it makes my binary bigger,

compile times are bigger." That sort of thing. But compile times isn't going to be an issue

if it's a library like that. But once it's a package, that'll have an effect. Although I think

on Linux, it is even part of it. Swift core foundation is binary. I'm not 100% sure.

But either way, you'll bloat your binary. You have more complexity if you pull in a dependency like

that. And in other cases, of course, you're going to import foundation because when you're building

an app, there's so much you need. You're eventually codable, all that stuff. You need foundation.

that's almost unavoidable. But it is a trade-off, you know, not every environment is the same,

not every system is the same. For some people it's a natural thing to pull in, for others it's

the last thing they want to touch. Yeah, it's a complicated subject to talk about because

you don't want to, or certainly I don't want to ever upset anyone if I talk about somebody's

open source work here and end up even implicitly saying, "Well, I wouldn't use it," then I don't

want to upset anyone. That has the potential to upset someone, but I think that discussion is

really valuable. Maybe we should just not call them recommendations because that implies some

degree of experience or testing or usage of a package that you're saying, "Well, I've used this,

and I therefore recommend it, which is certainly not what I do when we look through these packages.

I skim the packages, I look at the ones that look interesting, and then we talk about them.

Yeah, my process is a bit different, but I think that's also valuable that we don't do it the same

way, because that leads us to pick different packages for different reasons. Are you saying

you test every package you recommend? I actually do, yes. Just today, my pick today, I tried it,

it. I found a bug. I reported it. It's already been fixed. There's a new release. But I feel like,

I mean, that isn't always the case, but most of the time I pick packages that I'm really curious

about. And part of that curiosity is trying it out. And that's why I often mention that stuff

works in trying a playground because that's how I try it. That's the easiest way to try it. And

And that's a huge, that's a huge help in trying them, but today's package that

didn't work and I created a little package, which actually I realized I do in a

complicated way, so what I normally do is create a directory in terminal, the Swift

package, init, type executable, type library.

Actually today I just did an Xcode project new package.

It's so much easier.

It sets everything up that I had to fiddle around with and it's

immediately there in Xcode.

Sometimes you have these Jordan paths, you keep going down and you never reevaluate what you're actually doing.

But yes, I often do try it because I'm interested in those aspects of it.

How does it actually work? And that's later on.

That's actually a big part of what I want to highlight in that package.

How does that actually work? I was really curious about that.

And that's often the case, not always but often I want to see how it actually

works in practice. Well now you're making me feel terrible and like an amateur.

Which is exactly why I brought it up.

I'm not saying, although I did notice that halfway through your thing that you

said at the beginning you said I test all packages and then halfway through it

switched it off. And I'm not saying that I don't test any packages but it's

certainly, in fact I can give you a little preview, none of my packages that

I'm going to talk about today I haven't tested any of them. Shame on you.

Shame on me, absolutely. Well I think the ones that I don't test explicitly are

often ones I have used in the past. I'd have to check. I mean, I'm sure there's been one

or the other where I picked it for other reasons and I didn't actually run it, but...

You get a gold star then I will get one printed and send to you.

Oh, excellent. Excellent. What material is it going to be? Is it like valuable metal

or something? Is it an Apple-like trophy?

Oh, Apple-like. Yeah. Okay. We'll give you one of those little pens that Apple...

Little, there we have it. Little, little is the value of my work.

Right. But I think that's interesting though. I think that's definitely an interesting

discussion to have about what would be alternative labels for instead of recommendations, highlights.

Yeah. We've been talking about this with that pull request and the word that we've settled on there,

which I quite like is Showcase.

- Oh, right, yeah.

Yeah, it's a show, yeah, that's good.

I think that's really good

because that implies it doesn't have to be ready.

A showcase is often a prototype or a proof of concept

or just something interesting.

I think that's good, yeah.

- It can be a preview.

It can be, yeah, it's like here is a selection of things

that might be interesting.

- Yeah, no, I like that.

Yeah, I hadn't actually,

didn't remember what the final version actually was, yeah.

And we've also been talking this week about a blog post, right?

Yes, we have.

And that's a really interesting blog post that we came across.

It's called "Worrying about the NPM ecosystem."

And it's a blog post by Sam Bleckley.

It's actually quite, well, old in internet terms.

So this is three years old from June 29, 2020.

And this is really interesting for us in particular,

working on the Swift ecosystem and creating a package index on the ecosystem.

Because what Sam has done is analyze the NPM ecosystem through the lens of, of

what packages there are, you know, statistics of the package index.

And that's really interesting.

I mean, obviously there are many things that are different between NPM and

Swift, size being probably the most critical part of it.

- Well, it did strike me actually as,

it did strike me as I was reading through it again

before today's recording.

One of the, well, so first of all, actually,

I think it's really nice to see somebody step back

and look at a package ecosystem like this for the long term.

And we've got lots of history to look back on.

This is, the Swift package ecosystem is obviously something

that we're both very intimately connected with

and passionate about,

but there have been a great many package ecosystems

to learn from, NPM being one, of course,

but even back before then, CPAN

and lots and lots of package ecosystems.

And it's really nice to see somebody taking a long-term look

at like, well, what are the problems?

How is the reality of this ecosystem

compared to an expectation?

did strike me as I was rereading it that maybe we should put a limit on the

number of packages in the package ecosystem. So you know once that last

once that fifty thousandth package is in that's it we're full. Yeah some old ones

need to go. That's right yeah something it's not that that's it can never change

and I'm not really being serious about this but but there is actually there is

actually an interesting point to be at least considered of like, is there a

point where a package ecosystem, once it goes over a certain point, these problems

are unavoidable? I think so to some degree, but also there's inevitably a

layer of cruft that'll accumulate over time. I mean we see this already, right,

there are packages that are effectively unmaintained and have been unmaintained

for years and years and years.

They probably don't even compile on any, on any of the versions that we test,

you know, they stopped with Swift 4.2 or something like that.

I'm sure there are some, um, that we just ended up with and, you know, there's,

there's no process by which we would go through and drop them.

So we carry them forward probably forever.

I mean, unless we decide at some point, right, this, this isn't passing any, any

any compatibility checks never has or hasn't in the last X years.

Is that a reason to drop it?

I don't know.

Is it who's what's what's the

it's a good question that I don't really have a good answer for, but also we're in

a actually a much better position than we really should be because there was a point

I can't remember which Swift Swift version it was.

There was a point where we just had to say that anything, I think it was anything

three and below just had to go.

Like even though there was package manager support

for those, they were so old and it just didn't work anymore.

So we kind of had a reset around Swift 4, I think.

- I believe package dump failed to work

on very old packages, yes, or something like that.

And package dump really is central to how we gather

the very basic metadata for a package.

So if that fails, there's really very little to glean

from a package, yeah, that might have been the reason.

And so we had that reset and you're right

that there are definitely packages in there

that are so old that they don't compile

on any of the versions that we test with

and will probably never be updated again.

- Yeah, and what's to happen with them?

And you can imagine NPM is going to have a lot of that.

How old is NPM?

- Tens of thousands, yeah.

Oh, NPM is, I don't know, 10, 15 years old.

I mean, so in, in many regards, it's a glimpse of the future of

the Swift package ecosystem.

To some degree, I'm not sure size wise it's ever going to approach anything like it.

We should mention like in the blog post, Sam lists 1.3 million packages in the

NPM ecosystem, which is obviously more than two orders of magnitude, more than

we track right now, which is 6,000 packages and a few. I guess we're also not tracking all of them.

I mean, clearly we're not because those are just the open source ones, which is also true for NPM.

But we also are probably much less established as the source where everyone goes to register

the new packages. That's probably more true for NPM than it is for Swift package index.

So that's certainly a difference.

I mean, the size is just, I mean, imagine two orders of

magnitude, what that changes.

Um, and there are some other interesting aspects that he lists that he looked at

that I found really quite surprising.

So he looked at a, um, a thing, circular dependencies of packages, and that

is something I did not really expect.

So there are 1,700 packages that are directly dependent

on themselves.

- Yes.

- Which I can't quite grasp how that works.

- Well, he even says in his post, he says,

yeah, they depend directly on themselves,

either perfectly circularly or a different version

of the same package.

I have no explanation for that.

- So the other example I can understand

like 2,500 packages depend on themselves via two steps. And he gives an example that is quite,

well, it's still strange, but at least it makes a little more sense how it could happen.

There's Babel Core that depends on Babel register and that again depends on Babel Core.

But given that they're all related to Babel, you'd think, I mean, how would you build a dependency

tree where that can actually happen? I found that really strange. I wonder if there's something

particular about NPM that makes that possible. So we should say that the blog post is also

interesting for us because we want to do some of the same analysis for the Swift ecosystem soon.

We're not in a position right now to do it because we're not actually gathering all the

underlying information yet that we would be able to make that same analysis. But I'm really curious

that can actually happen. I think part of this is

is actually a little bit specific to JavaScript the language. We talked about

Foundation earlier and JavaScript is a very very lightweight language and

doesn't have anything like Foundation and so yeah part of the reason that are

1.3 million packages is that a hundred people have all tried to solve all the

basic problems and they've all put a package out for all the basic problems

And those packages get deeply, deeply ingrained in those dependency

graphs. And I think that's a lot of these circular references are caused at least

in part by that problem. Yeah, that's actually in one of my first notes about

what are potential lessons. I think that's really it because a lot of the

analysis that Sam is doing is, you know, highlighting his surprise at how many,

how deep the dependency trees are and how wide they are.

So how many dependencies get pulled in?

There's, there's, um, many packages that have 250 dependencies and no, actually

2,500 dependencies is the maximum.

And, and I think, uh, 2,500, 2,500.

Yes.

Yeah.

Sorry.

I was quoting from Crates, from Rust comparison.

So there's very, very, very, very deep dependency trees.

And I thought about how or why that is.

And I think you're exactly right.

That's why what I thought as well, a strong and good standard library probably

trims that tree by a lot because it literally prunes the tree of all these

packages that other ecosystems don't need.

And I think the other one is UI libraries that are practically always

OS libraries that aren't part of the Swift ecosystem per se.

Like, like we're not tracking Swift UI as a package that has sub dependencies

or anything like it, UIKit equally.

That that's all platform libraries, which NPM really doesn't have, right?

any, any web framework and there are lots of them needs to ship all this as a

dependency, right, that you then pull in and use.

I think an area where you see the same issue is web development.

And, and we are actually the, that's interesting.

The SPI server package is the package with the most dependencies and it's 56.

Uh, and that's mostly, um, the vapor and friends because that's a very rich

framework with lots of dependencies. Vapor has everything nicely broken down into individual

things. If you use a database, you by nature use the foundational Postgres library, then

I think there's even a separate one for the Neo stuff and then there's a fluent layer.

I think so I have at least three, maybe four database libraries that you pull in when you

use Postgres as the database in vapor.

And that is the case for quite a number of other packages.

I should also add in our defense, those 56 includes def dependencies.

So it's not, it's not entirely that, uh, that bad in the, in the shipping binary.

But I think we are sort of an example of a more typical NPM package in that sense.

in that a lot of stuff isn't OS library stuff.

I mean, I don't think, I'm not even sure the Postgres,

I think the Postgres stuff might need libraries.

I need to check what we actually need in our Docker image.

But a lot of the stuff we build to run is very foundational

in the sense there's very little that the OS

actually provides as underlying libraries that get used.

A lot of it is just straight up code

that is built on purpose to provide the functionality itself.

What I also found interesting,

and I'm not sure if you've followed that link,

there was a follow-up post where Sam looks

at the same analysis for Rust,

and that was quite interesting.

Did you see that one as well?

- As I skimmed that one,

but I didn't read it in full, full depth.

- Yeah, it's a bit interesting and particular for our case,

because it's sort of in between.

So Rust at the time, this was July, 2020,

had 50,000 packages. So we're just an order of magnitude away now from us.

It also includes cycles, dependency cycles, so that might indicate that it's just something

that happens. CB; This is the ghost of Christmas future.

MG; Yeah. And a lot fewer dependencies. And I think that is to our point that a strong

standard library probably prunes that tree quite a bit. And he mentioned that, Sam,

It's very likely due to a few very popular packages with few dependencies that early on

caught on and were crystallization points for all the work.

I think Swift is in a good position, especially with many of the packages in backend development

and Swift server group, SSWG packages. Swift Neo, for instance, is taking care of a lot of the

plumbing in terms of networking, where Swift benefits from having packages in lots of areas,

but not multiple different implementations. So there's typically one good library that does it,

and all the effort to maintain it is focused on that one library. And then it gets used a lot and

battle tested and sort of often they have good dependency trees in the sense that there are

few dependencies that they themselves have, or it's the same ones again and again. So I think all

of this helps a bit in keeping this growth in check. But obviously it's going to be interesting

to see if that changes and how that changes as the index ecosystem grows.

Stay Forever It will certainly be something we have to keep

an eye on. While you were just talking, I had a suspicion and I just double checked it.

So we have actually two dependency trees in SPI Server. As you say, our Swift dependency tree is

quite large because of vapor in the database dependencies that we bring in through that.

We also have a JavaScript dependency tree because we have a front-end process and that has its own

build process and we use the standard JavaScript dependency manager that we've been talking

about today. And I did pick our dependencies very carefully with the front end and I've

just double checked. We have three top level dependencies and those dependencies have

zero second level dependencies. Oh nice, I was sort of racing myself for a big number there.

No, so it's actually we're the opposite, we're living in opposite world.

Wow. We do have, so I should just mention, we do have a much bigger results file because

in production we only have three dependencies but our build environment gets into that whole messy

NPM tree. So we have some development dependencies and we have some production dependencies and our

development dependencies are much messier than our production ones. Right, right. Yeah, I need to

to check, I'm actually curious how many Swift production dependencies we actually have.

I mean, it's not going to be a lot because we have snapshot testing and that sort of

stuff, but there aren't. I can't think of a lot of specific test dependencies that we're

pulling in.

Toby

Obviously we'll put it in the show notes, but I would thoroughly recommend reading this

blog post if you have even the slightest interest in what we've been talking

about because it's fascinating. Well written, it'll make you laugh a couple of

times. It's a great blog post. Yeah, really good and I'm curious. So we'll

definitely endeavor to produce the same numbers, same statistics for Swift

Package Index. We're just not in a position to do that yet because we're

not tracking the full dependency trees but it is coming. Well I think

it's also good that we're thinking about this while the package ecosystem is this

size. Yeah. Because I think one of the ways that you stop it happening is by

showing it happen. Well the question is can you really? I mean how?

Like we were saying earlier I mean I do believe there probably is a size at

which this becomes inevitable but certainly there are things you know I

I think we're in pretty good shape to delay that inevitability at least a little bit.

Let's see how it goes.

So should we showcase some packages?

Let's showcase some packages.

You can kick us off this week.

All right, I'll kick us off.

So my first package is actually two packages in a trench coat.

And I do suspect one of them might appear.

depend on each other, right?

Actually they do, but it's

unidirectional.

I suspect they might also be in iOS Dev

Weekly later this week,

but I'm calling first dibs. And it's

from our

good friends Point Free. It's Swift

macro testing

and Swift snapshot testing.

Disclaimer, Point Free Co. are a sponsor of

the Swift Package Index,

but I just can't resist. I'll

always recommend them. They're good packages, Bront.

I saw both of these in the RSS feeds and as soon as I saw them, I just skipped over them

because I needed to pick them up. You left them for me, nice. Yeah, they're really great. What

I love about them is that they are useful, but also useful in interesting new ways. And they

really build on top of each other. So, right, let me explain what they do. So, the first one,

Swift macro testing is about macros which is a new feature in Swift 5.9 and Swift 5.9 obviously comes

with the ability to implement macros. It also has some facilities to actually test your

implementation and what it does effectively is it adds an assert macro expansion and then you can

inline, you know, have a literal string that is your expectation of what it should look like and

the macro definition itself and then it compares that the macro expands into what you wanted it to

expand to. And the Swift macro testing package expands on that, no pun intended,

by giving you more capabilities because the assert macro expansion test, while nice,

is fairly basic. So it only allows you to compare the strings and you sort of have to manage that

yourself, what this, their, uh, assert does is it actually puts the expanded

expectation into your source code in line.

So you don't need to prepare something and then copy paste it in.

You, you write an assert with the macro definition in it, as you call it.

Then you run the test.

You know, if you know how snapshot tests work, you normally run the

test and then it writes out a file.

And then you confirm, yeah, the file looks like, like, you know, as I expect.

And then when you run run it the next time and the file is there, it just compares the

next snapshot against the file.

Right.

What it does here is it, it is not file-based, but it actually places the expansion into

your source code in Xcode and it uses Swift syntax under the hood to understand your

test structure and does effectively a live live source edit of Xcode.

source edit of Xcode, so it as if you were typing out the expectation itself.

So that's quite nice because you don't need to fiddle with the expectation.

And obviously, once you've done it the first time, it'll then, if it's different,

it'll highlight a difference, right?

It only does that if there's nothing there yet.

So this is your first capture of the difference.

And it goes beyond that because it doesn't just snapshot your expansion,

it also snapshots diagnostics and fixits, which is something that the built-in

certain macro expansion doesn't do.

So this is only for testing the expansion itself

and Point Free Co's tool also allows you to test

all the edge cases, like diagnostics when there's something

wrong with your macro call or fix-its when you want to test

what your suggestions are, how to fix issues

with the macros.

So that's quite nice.

- So I think I did see the macro in the first place

macro package fly pass, but I didn't look into it in much detail yet. Like I say, I

knew you would take it. But what I did see was, I think, what you're about to talk about,

which is the other side of this, which is an enhancement to Swift snapshot testing,

which added support for inline testing this week. And even now I understand why they added

that. But that feature, even on its own, is invaluable. We use snapshot

testing in a couple of different ways. We have HTML snapshot testing, which takes

fully rendered HTML files of hundreds and hundreds of lines of HTML

and snapshots those. And those obviously suit file-based snapshot testing really

well. But then we also have a whole load of other uses of snapshot testing. Like

snapshot tests and SQL queries and we snapshot test even just a bit of like

JSON like in a fragment of JSON somewhere or even just a string like we

you know we render a date or something maybe we'll just snapshot test that and

currently all those live also on disk which is it's okay it's not terrible but

I really liked the idea of being able to have those snapshots just in line in the

in the code and and now finding out that they will automatically update if you if

if you ask them to, that's just the icing on the cake.

- Yeah, that's really nice because you always have to

sort of make the decision.

I mean, it still doesn't make sense to do an inline snapshot

for hundreds of lines of output.

That's clearly something you want to stick in a file.

- Of course.

- But many smaller ones are just really nice to have inline

because you don't need to go hunting through the file system

to actually look at the snippet, right?

It's really nice if a three-liner, four-liner

is actually inline there in the test.

And that's this amazing new feature of the inline testing.

Not only that you can have it in there,

but it actually automatically manages

that representation inline and you just,

effectively you just look at it,

yeah, looks all right, run it.

And then if it fails, it gives you the same message

as if it was a file.

And obviously also you can always see the diff

in your source tree, even if you were to save it.

That's great. It sounds like a real, um, a real, uh, enhancement to, to,

to the Snapchat testing library.

Really great couple of packages, um, and, and really nice, um, combined,

um, yeah, release of those.

So my first, um, completely untested and, and experimented with package

is, um, is, I mean, so, okay. So, so it's, the package is cloud's

cloud kit sync monitor.

So in order for me to have tested this,

I would have had to set up a CloudKit project.

And you know, there's a lot of testing in that.

It's by Grant Gruninger,

and it monitors the state

of an NS Persistent CloudKit container

synchronization process.

So I think this,

if it does what it says on the same,

which I'm sure it does,

I think this is a potential,

a package that potentially every CloudKit application should include because one

thing, one area where CloudKit is a little weak,

certainly in the operating system and in also in applications that use it,

is feedback on what's happening with CloudKit sync. Has it finished?

Is it still going on? What's happening? Did it error?

And this allows you to hook into all of the notifications sent out by the

persistent CloudKit container and translate them into some published properties

that you can then monitor in SwiftUI and update some UI

or keep whatever tabs on it you would like in an easy way

without having to subscribe

to all those different notifications.

And it doesn't come with any pre-built UI

as I believe it shouldn't.

I think that's something that you should,

each application should determine

how to surface this information if they choose to.

But it does kind of tame all those notifications

and give you a nice way to just take a look

at what's happening with your sync state.

It's got a great read me file.

It's actually been in development for a couple of years,

but I've not come across it before.

- Nice.

Yeah, I mean, that's super hard to test.

Actually, as you were saying it,

I realized I did not test the macro testing package.

So there you go.

It's immediately--

- See, I knew it wasn't.

I knew your virtue wasn't as complete as you claimed.

- But snapshot testing I have, I've tried.

- Well, we've all used snapshot testing.

- All right, we all have.

(laughing)

Right, my second pick is called Lighter by Helge Hess.

And this is a really interesting package.

It's not new, I've known about it for a while,

but there was a release in the last week

or last couple of weeks.

And this is the package I was alluding to earlier

when I said I was curious

about how it's actually implemented.

So Lighter is a very interesting SQLite database

access package.

And this is probably an area where there are quite

a few candidates in the package index

that is well serviced.

There's a rich field.

Like for instance, there's GRDB by Gwen Del Roy.

That's probably the most widely known and used representative of the package,

of a SQLite database access package.

But Lighter is really interesting in its approach and its use case, effectively.

It is a package that source generates SQLite library bindings.

And it can do that in two ways.

One is just straight up a layer that directly interfaces with the C library.

So it's dependency free what you get out of it.

And the other one is a, it generates an additional layer on top, which is a lighter

layer, so it gives you a nicer high level API to talk to your database.

But what's really interesting is the, so the marketing, if I can call it that of the

packages, it's, it's really, really fast.

And it has a performance test suite where it calls some numbers that are quite remarkable.

So in some of the tests, it's six times faster than GRDB.

And it's three times faster than GRDB if GRDB is sort of manually tweaked,

effectively by avoiding codable, which is apparently a very big price to pay there.

So it is quite fast in the tests that Helge is running. But I was really curious about some of

the things he's doing in his examples because he has an example how you filter on a query. So,

you know, as you can imagine, you run a database, get me all the records from a table and filter,

you know, like a typical where clause. But it's written like a Swift filter with a closure.

you have, for instance, I loaded up a music, there's a Chinook, I think it's called a test

SQLite database that you can download, which has sample data in it and has tracks like music tracks

in it. And you do db.tracks.filter, and then you pass in a closure where you can apply

a filter on the tracks individually, right? You do $0.length, like the track length,

And then I queried for all the tracks that are longer than 300 seconds.

And that runs, I mean, obviously with the number of tracks in it, I wasn't

able to tell if it's fast or, or anything, but I did actually check how it's

implemented and that was really interesting because what it does

effectively, it binds the, the closure as a C function pointer into, to

the, to the SQLite library.

So the library actually runs your closure directly, like as a function

in inside the database, you know?

it's as if in a Postgres database you had shipped your code as an extension and then called into it.

You had all this done ahead of time and then you were calling into it. It can actually do that with

straight up Swift code. I was really surprised that that works. I mean, obviously there's some

unsafe pointer stuff going on to make that work, but that explains how that interface works and

how the claims can be made that this works without having to translate all sorts of variants of Swift

code into where clauses, right? That's not happening. It's actually just executing the

predicate directly in C in the library. And that's remarkable. So yeah, it's a really interesting

package. I tried it out with the Chinook database works as advertised. It code generates. So there's

a build plugin that comes with it that auto generates your database access layer. You

give it an input database and it looks at the schema and pulls out all the stuff. And

that worked fine for that database. Well, it worked fine actually. That's the thing

I pointed out earlier. There was a formatting issue in the underlying database and that

broke the generated code and Helga fixed that really quick. And that's the one thing I had

in my notes when you adopt that sort of library that generates code, there's a slightly bigger

risk that things might not go 100% if the code generation doesn't work right. So yeah, you have

a bit of an extra risk there in your dependency. On the other hand, if you don't regenerate right,

what you already have is going to keep working. So at least there's some safety there, but it's

It's something to bear in mind for packages like this.

But I believe if you need a really fast

SQLite database access and you don't want to deal with

the C aspects of the SQLite database,

which is a database library,

which is probably not something you want to be doing,

this looks like a really great option.

- That's great.

And I like how in the description of the package,

it ends with dependency free.

So it says Swift APIs for SQLite,

type safe down to the schema, very, very fast

dependency free.

I think, you know, the fact that it's made it

into the description of the package is obviously,

that's how important Helga is taking it there.

Although I would argue it does have a dependency on SQLite.

- On SQLite, yeah.

(laughing)

- But I think we'll forgive him.

- Well, on Mac OS and iOS and everywhere,

the library's there.

It's probably only on Linux where you--

- So then we get into defining how do you define

the dependency?

(laughing)

- What's the dependency?

- But let's not go down that route.

- It depends.

- Instead, we'll go back to my un-researched,

un-tested list of packages.

- You really gotta have one up, won't you?

(laughing)

- Well, I was gonna say, actually this one,

I haven't tested this version of it,

but I have used this package in the past.

It is shipping in the iOS Dev jobs app,

which uses SwiftUI Introspect by David Roman.

And I have a feeling we've talked about this package

on the podcast once before right at the very beginning,

because I think I just started,

I just finished using it in the app

when we were looking for packages to talk about.

And I think I talked about it then,

but I'm gonna mention it deliberately again,

because it's just hit a 1.0 milestone.

which is always worth celebrating,

especially for a package that is so good like this.

What it does is it allows you to get at the underlying

UI kit or app kit controls underneath a SwiftUI view

in a safe way so that you can,

if there is something that the SwiftUI view

doesn't quite do, it means you don't have to completely

throw that SwiftUI view away.

You can, if it is based on a UI kit or app kit control

behind the scenes, you can get access to that,

modify whatever properties, call whatever methods

you would like to on that object.

And it does it in a safe way so that if the underlying

implementation of SwiftUI changes,

it does not crash your application,

it just doesn't set those properties.

Now of course, if you do something in that code

that you then 100% rely on later,

That's your responsibility to make sure that

if that code suddenly goes away,

your application should still at least work.

But this is a really great library

for filling in those little gaps.

And those gaps are getting less and less every year.

There will be a happy day,

and I'm sure David will agree with me

that it will be a happy day when he can say,

this library is no longer necessary.

And there will definitely come that point.

One of the things that I liked that has been added

since I used the package,

which is an opt-out by default to new versions.

So when you introspect something,

let's say you're looking for a scroll view

inside the SwiftUI scroll view,

you now have to say, I'm looking for it on iOS,

version 13, 14, 15, 16,

And then if version 17 comes out like it just did,

you would have to manually opt in.

You could say like I've tested this on the new version.

I checked it.

I'm gonna add that additional case

so that it enables my introspection on the new platform.

Yeah, I think it's a great library.

It supports, there's a huge list of controls

that it supports, everything from page controls

scroll views, to steppers, to tables, to all the different lists and grids and

things like that. It supports an enormous amount of the SwiftUI API. It's

been around for a long time. It's been around for three years now, which I think

is pretty much as long as SwiftUI has been around. Wasn't SwiftUI's first year

2019? I think so, yeah. Isn't it SwiftUI 3.0 or something?

Well, if it's 2019, wouldn't it be four? So yeah, maybe it was a few months after SwiftUI

first showed up, but it's certainly been around for the vast majority of SwiftUI's lifetime.

And I can recommend this package because I have used it.

Nice. And with that, I think we'll call it another episode, and we will be back with

and some more showcase packages next week

and more news from the Swift Package Index.

So we will speak to you in two weeks.

- See you in two weeks, bye bye.

- All right, bye bye.

[ Silence ]