29: Are you saying that visionOS is more important than my sitemap?

I have a prediction for your recommendations on today's podcast.

And I know we're not talking about recommendations yet, but I want to make this prediction before we even get started.

I predict that all three of your package recommendations today will be Swift 5.9 only.

Interesting. Should I give you the answer already?

You can give me the answer. Yeah, sure. Not what they are, but the...

[BUZZER] Well, actually, let me check because I'm pretty sure that it's not 5.9 only. Oh,

it's not. No, no, I would have bet that it isn't. No, there's one that isn't.

Oh, interesting. I have the other way around. I have one that is and two that aren't. So,

between us, we have a full set of 5.9 only packages.

- Yeah, I mean, there's lots of interesting stuff

coming in, right, on 5.9, lots of macro-related packages.

- Lots of macros, yeah.

I think it proves that we did the right thing

getting 5.9 into our compatibility testing

as quickly as we could.

- Yeah, yeah, I am a bit bummed out

that we can't support or don't support

the product filter yet.

I mean, we might talk about that at least briefly now

and as part of the news, right, the plan was to support the product colon macro clause as a filter.

But we can't yet. And the reason is that products aren't declared in the, macros aren't declared in

the Swift package manifest as products. They are targets. And then they get added to a library and

the libraries, the products. So we have no way of distinguishing them at that level to support

our filters because our filters really look at the products that are declared in a package.

We have some thoughts around how to fix that. Unfortunately, the straightforward way of doing

that and supporting that is not possible right now. So bear with us. I've seen that some packages

actually have macro in their keywords. So if you search for macro, you still get them, you get a

a decent list, but it's obviously, you know, there are some, I guess there's a package

called macro that'll end up in there that has nothing to do with macros themselves.

So this is not as strong a filter and we hope we'll be able to improve it, but some authors

have worked towards being discoverable in that way. So that's actually nice.

It's also probably worth just mentioning how people can add keywords to their packages

is because it's a slightly opaque process

of we pick up keywords out of GitHub keywords.

So if you would like to add the macro keyword

to your Swift package, you need to go to GitHub,

add the keyword there,

and then we'll pick that up within a few hours.

And then once you do a search

on the right-hand side of the search results,

you can filter on keywords.

And if you then hit the macro keyword,

then you'll get everything that's tagged with a macro.

But I've been working the last couple of weeks

on something that has absolutely nothing to do

with Swift 5.9.

And it's actually something we've talked about before.

And I'm not gonna go into a huge amount of detail

because much of it is not particularly interesting,

but there are a couple of things

that I think are worth mentioning.

So just to clarify what the feature is, first of all,

I've been working on sorting out

our Google indexing problems.

So Google has, Google loves our package pages.

It sends a lot of people towards our package pages.

And I think it understands that bit of the site really well.

And then as we put documentation hosting onto the site,

Google loves us less for the documentation hosting.

And there were a couple of problems.

The first problem was we were hosting multiple versions

of each package's documentation.

And some of those package documentations are identical

because even though the package has had a new release,

the documentation may not have changed.

It may have changed, but it also may not have changed.

And so Google really hates duplicate content in the index.

And so what it saw is it saw,

okay, here's one set of documentation

and here's another set of documentation.

And I don't think there's any differences between the two.

And it actually started to punish us for that

by removing some of those pages from its index,

which is what it'll do

if it thinks you're trying to game it,

which our intentions were true,

but our actions made it look like we were trying to game it.

(laughs)

So obviously we want to have

multiple versions of documentation.

That's part of the feature that we built.

We want people to be able to go back

to previous major versions.

We want you to be able to see the difference

between the documentation on the default branch

and like the latest stable release and that kind of thing.

But so the first thing we had to do was let Google know

which version of each package's documentation is canonical.

And so every page in the documentation,

In fact, most pages on the site now have a meta tag

inside the HTML that says, if you fetch this page

and it's not the canonical version,

here is a pointer to the canonical version.

So all of our documentation pages now link

their canonical page as the latest

stable releases documentation.

So that was step one.

And the second step is then to start to tell Google

about all the different pages we have

on the documentation site.

And that is actually what I want to talk

a little bit more about and in more detail about,

because that's where it gets more interesting

that for people who are not running a package index,

which the first one is like very much a specific problem

that we just had, we've tried to fix it.

hopefully, you know, these things,

it'll take Google time to trust the site again.

And it's, we're already seeing some results, which is good.

Pages are going back into the index,

but it's a slow process.

So before we move on to going into detail

about how we're gonna tell Google

about all these documentations,

I do just want to mention that we had some contributions

on solving this canonical URL problem from Toby Herbert,

who noticed several issues with our canonical URLs,

mainly to do with kind of casing,

letter casing in some of the URLs,

because we honor the case from GitHub of like,

if you have your owner name and your repository name

with a specific case, we honor that.

And our canonicals, we're not honoring that correctly.

So in addition to some of the work that I did on that,

others like to thank Toby for all of his work on that.

That was incredibly helpful.

Most helpful actually was spotting the errors,

which is always difficult.

So yeah, the bit that I actually wanted to talk about

in a bit more detail is how we tell Google

or any search engine about all the pages

that we have hosted on our documentation site.

And we use a feature, it's actually an undocumented feature

of DocC for this.

And what I'll do is I'll link an article

in the show notes from Joe Heck,

who documented or wrote up a potential use for this flag

and also how to find and add this flag

to your documentation processing.

So the flag is emit digest.

And if you add that flag onto the end

of your documentation generation command,

you will get a few extra JSON files in the output.

And one of those files is called linkable entities.

And it's a collection of effectively

every individual piece of documentation

in the built documentation that you've just generated.

And so what we're doing is we're using that file

to pull out all of the paths

to every single documentation page

in a packages documentation.

And then we are creating a sitemap

out of that set of URLs.

So we're effectively saying,

give me all of the URLs in this documentation.

And then we'll make a sitemap that will tell Google,

look at all these different pages that we have

underneath this packages documentation URL.

And if Google then goes and fetches those,

it will get correct canonicals for all of those.

So we're hoping that the combination of those two things

is gonna be a good fix to the Google problem.

But the reason I wanted to mention this flag

is that it is something that you may want to run yourself.

So if you are creating Doxy documentation,

you might want to extract or generate this file

as part of your documentation build

so that you can have a sense of all of the different paths

in your documentation

so that you might create a manual curation

of here are the most interesting bits of this documentation

or maybe the order in which the documentation gets presented.

And again, Joe, in that article

that we're gonna link in the show notes,

he has a good bits of advice on how you can do that

in the real world.

- Right, and that's actually a massive amount of links,

isn't it?

The site map and the total number of pages

that we're effectively, or have been serving,

we just never really realized how many it is.

You had a figure, didn't you?

- We do have a figure, yeah.

When Google ingested all of these site maps,

it now tells you how many URLs it found,

not only in the kind of master site map,

but also in all of the different site maps that it found.

And it found over 250,000 URLs in the swiftpackageindex.com,

which is way more than I thought we served.

- Yeah, well, we've got 6,000 packages,

but the documentation obviously dwarfs everything, right?

That's just lots of symbols.

- It does, and I think there's actually something

that's kind of interesting in that as well in that.

So, it's actually, in fact, it's one of us,

supporters stream the company who kindly helps to sponsor the site. They have a package which,

on its own, has 50,000 or 48,000 URLs in their documentation.

Mason: Wow.

Hartmanis: And yes. So first of all, congratulations on being the biggest

documentation site by an order of magnitude on the Swift package index. That in itself is remarkable.

I think one of the things that potentially needs looking at in terms of Doxy in general

is how many pages it creates, because I can assure you there are not 48,000

useful documentation pages in that package's documentation. The vast majority of those are

are contain almost no more information

than you could get from just looking

at the function signature.

And in fact, a lot of them are because they're inherited

from like Vue or something like that,

they pick up a whole load of documentation pages

for that as well.

And I think-

- Right, right.

- That's potentially something that, you know,

it's a difficult problem to solve.

Like, do you just not generate pages

for if they don't have like proper document,

Like what even is proper documentation, right?

It's a difficult problem for DocC to solve.

But I think that potentially there is

an interesting discussion to be had around

what that balance is.

And certainly I don't think 50,000 URLs

is the right balance.

It certainly seems like the wrong side of useful.

Now there's the other side of that,

which is who should care whether we host 50,000 documentation URLs for one package? As long

as you can find the bit of documentation that actually solves your problem, it doesn't matter

that there's a whole load of unused documentation pages. So there's no kind of clear cut, like

there's a clear solution to this problem. But it is something that I would really enjoy

talking to the Doxy team about actually.

Well, it does matter a bit, right, because we are running up to certain limits in sitemap

files, aren't we?

That's true.

Yeah.

So we do need to think about chunking stuff and it sort of gets a bit more complicated

downstream or, you know, at our end and putting it all together because, you know, it's not

just a single package.

It's like we have, I believe, 400 documented packages now.

And obviously, you know, that they all come together in the sitemap.

Now we can treat them individually as package pages,

but this is a place where they all come together

and we need to funnel them through one site map.

And that creates certain challenges,

just like it created challenges

with the size of the doc sets early on

that we needed to solve.

- So the limit that Sven is talking about there

is that site maps themselves have a 50,000 URL limit.

So if you have one sitemap,

and we are now doing one sitemap per package,

if you hit that 50,000 URL limit, then Google,

actually, I'm not quite sure what it does.

Does it just stop reading at 50,000,

or does it invalidate the entire file?

That's a good question that I don't know the answer to.

But what we should probably do there,

and you know, Srinivas talked about this the other day,

but since then I've thought about it a little bit more.

I think that we should potentially,

rather than go into the rather complex solution

of having multiple sitemaps for a single package,

which we're not actually quite there yet

because the biggest package we have

does only have 48,000 URLs in it.

But I wonder if we just clip the sitemap at 50,000

because a sitemap is a guide to Google

to Google and what it you can tell Google about all your pages with a

sitemap but from each of those pages it should go and crawl from there so it's

not like if those pages are not in the sitemap they'll never get crawled

they're less likely to get crawled and less likely to get crawled more often

but if we're at 50,000 per package I think we may we may cut our losses at

that point. Well it would be nice if there was a way of ordering them right I

I mean, if Doc C had a means of putting the ones at front

at the front that actually have, you know

user contributed documentation, because I suspect lots

of them just have the default pages perhaps, right?

Because no one has documented 50,000 symbols.

So if there was a way to put that to the top

then that would solve the problem really.

- It really would.

And at that point we could potentially even say,

well, actually the maximum that we'll have is

let's say 10,000 or something like that.

But there are lots of different ways to solve this problem,

but I thought it was an interesting point of discussion,

first of all.

And secondly, that people may not know

about this emit digest flag at all,

because it is an undocumented flag.

- Yeah.

Nice.

Well, the other thing we can briefly talk about, I suppose,

is the big thing that happened last week, right?

VisionOS was released, like the SDK was released.

And that happened a bit sooner than I thought.

- Are you saying that the release of VisionOS

is more important than my site map?

(both laughing)

- Well, you know, it's funny, I'm interested in this,

but I haven't actually watched a single WWDC session

about VisionOS.

I've been more interested in some of the 5.9,

macro stuff, tooling.

And I, I thought about this.

I've early on when iOS, you know, the SDK came out, I dabbled a bit with it, but

I've always been, I've always been interested in writing apps and creating

that.

And I've done a bit of that, but I always ended up drifting towards tooling.

And I think, I think this time around, I've, I've sort of, I'm leaning in because

it seems like, you know, it's the gold rush again, or I suspect it will be to a

When this becomes really mainstream, I mean, the $3,500 device won't be the thing that starts this, you know, bringing AR apps into the mainstream, but the subsequent devices will.

So at some point, I suspect we'll have another gold rush where people come up with cool app ideas and put them out.

But I feel like I'm going to be the one that sells the shovels, not the one that's going after the nuggets.

(laughing)

And I think with the index, we're in a good position

and we actually have started shoveling a bit, right?

We have rushed to start supporting VisionOS

on top of the 5.9 that we've just added.

I mean, we weren't completely caught by surprise,

but it came earlier than I thought.

I thought when they said later this month,

I really thought, well, it's going to be this week

that it's going to drop.

but it happened just one week after WWDC.

So yeah, do you have any plans?

Are you curious about VisionOS and building apps?

- Yeah, I'm tremendously excited about the platform.

I think it's the kind of thing that watching people explore,

I also haven't actually written a line

of VisionOS code yet,

but watching people experiment and bring their apps

into the environment and kind of start to build them

with that SDK, but actually just thinking more about

now that we have a road that we're kind of,

we've got a wheel on the road

towards what AR could potentially become one day.

And I am quite excited about what AR

could potentially become one day,

and this is the start of that path.

And so while I haven't written anything yet

and I don't have any plans for a VisionOS app,

I am quite excited about it.

- Yeah, well, it's certainly, I mean,

the samples look nice.

I think I came out of WWC a bit unconvinced

regarding the use cases.

I mean, we had the discussion beforehand

and I recall saying, I'm really curious

what Apple are going to present as the use cases.

And I don't think that has truly happened yet, perhaps.

Who knows?

I mean, there's still time.

There's certainly going to be a, another sort of introduction once it actually

ships.

So maybe that will change.

But, um, I, I haven't seen any super, super obvious app, you know, that, that

would make you jump up and say, right, this, I need this, this, this is a thing

that's, that's totally different from, from all other apps.

Have you seen anything like that?

Is there anything convincing?

I think the convincing bit is actually the fact

that it is going to run what are quite standard apps

that you might see on your iPad or your iPhone

or something like that.

And I think that the,

I think there's two exciting things going on here.

We're on a path to a potential very exciting,

very futuristic AR type device.

But I think that's a long way away still.

And then you have this potential device that could,

I think, be used quite effectively in a work context.

And I think having apps around you and having,

I think the concept of kind of screens is interesting

and having apps separated from screens is interesting.

And I don't think there's any specific app

that I'm excited about,

but I'm excited about seeing what that work environment

maybe looks like. Yeah. Yeah. I mean, I think it's, it's easier to see the useful AR app

that'll completely change how you do things once the device is like actual glasses. Right.

I mean, I think that's, for me, at least it's, it's hampered by, you know, I wouldn't, I

wouldn't walk around with that thing. I mean, even if I had one, right. You're not, you're

not... Nor should you and nor do Apple want you to. Yeah, exactly. But I think they don't

want you to because right now it's not that kind of device, right? I think if they were

able to ship like real literal glasses, that would change the story of that thing. Which

is, I think we're sort of seeing right now the prototype version of obviously way more

polished than a prototype that Apple typically don't ship, right? This is like the breakout

iPhone on a board with a screen and all the parts spread out a bit and a lot bigger than

it was in its final first 1.0 shipping shape. It almost feels like it's a change in that

they actually released this now to give everyone a glimpse of what's to come way earlier.

Yes. And I think I wrote a little bit about this in Friday's iOS Dev Weekly, but one of

things that I was convinced was just a, you know, it was a feature that was being lined

up for whatever AR device that they released was last year in iOS 16 they added an AR feature

for accessibility where if you were holding your phone up and approaching a door, it detected

the door and it warned you about the door and it told you the information about the

door whether it was push or pull or that kind of thing and that was such a

clear feature for a headset of some sort. Like nobody holds their phone up in

front of them while they're walking around. It's not practical to

really do that and so it felt like this is so clearly a feature

for a headset and yet of course the headset doesn't do that and the reason

is you shouldn't be walking around with this headset any more than you

you should be walking around with your phone in front of you.

- Yeah, it's not that kind of headset yet, right?

That changes the whole pitch, yeah.

- Yeah, I'm confident that we'll see that feature

at some point in a device that you are intended

to walk around outside with.

- Yeah, yeah, absolutely.

Right, maybe to just bring this briefly back

to what we're doing.

So, platform, VisionOS platform compatibility testing

is coming, it's coming along.

In fact, the builder tests have just all passed.

So there aren't any, we're all set up.

We just have to just,

we just need to do a little more typing

and then we're done.

- It's not just typing.

- Yeah.

There have been some difficulties adjusting our test suite

because we're once again in a state where

there is no single macOS version

on which you can run all of the Swift versions

we support which is the four latest point releases so 6, 7, 8 and 5.9. And this is just my eternal

wish that at some point we won't be forced to update the OS and Xcode versions and then have

machines that can only run you know a small set of those four. I mean ideally would be even more

than four. I just want this Linux docker thing where any Linux can run any Swift version in it.

a Docker container.

And you're not going to be happy on something else.

Yes, oh god, I want this so much.

I want this so much.

I mean, I do think we need to consider virtualization at some point because it's getting really,

really, it's tricky because it also impacts our regression test suite.

It's really hard to keep testing package versions that used to fail on 5.5.

I mean, we're not even testing for 5.5 anymore, so I've just moved them forward time and time

again, to the oldest version that we support. But at some point you lose the capability to build

those packages with the older Swift versions or the newer ones. And the test cases we were

actually testing for aren't valid anymore. And it's really hard to keep that regression test in place

in some shape or fashion. I mean, because there's still value in the test, it just happens that we

don't have a package at the right version or Swift at the right version to still test that. So

So that makes it quite difficult.

And I wish that part of it was easier for our setup

and not having to manage our machines like that

and decide which one we're pulling forward.

Then we lose capacity on other Swift versions

because the latest one can only build 5.9

- Yeah.

- And so on and so on.

And on Linux, we just never have to do anything.

It just, any Swift version, we can just run.

- Yeah.

So we're currently split back across three distinct operating system versions.

Again, we have, um,

Monterey compiling five seven or anything with Xcode 13,

um, Ventura compiling anything with Xcode 14,

which is five seven and five eight maybe.

And then we now have a Sonoma, uh,

build machine that is now running, uh, beta two with the vision, OS SDK,

which to bring us back to our original point, uh,

we hope to ship soon. Yeah, I mean, by next time recording, we'll

definitely have it. I think we'll have it next week, if not late this week. Depends

a bit on when you would want to pull the trigger to actually deploy it, but it

might happen tomorrow or the day after. So, and that will be

very exciting because we'll then have compatibility status for all of our

packages with with 5.9 and the VisionOS SDK. Yeah, yeah, first new platform

since we added ARM testing, right, which was arguably, I mean it was a proper

platform in our matrix at some point, so interesting times. So we've done

quite a lot of talking about package index this week, so I think we should

move swiftly on to to some package recommendations. Would you like to kick

All right, I'll do that. The first package I have is called metacodable by Soumya Ranjan

Mahunt, and I hope I pronounced that correctly. This is the first of two macro packages that

I'm going to talk about, and it's a very nice package to tweak or empower codable performances.

And the best way to describe this is, imagine you have a codable struct and you have a field

And you've given it a nice name in Swift, but the codable, you know, the JSON

file has a different name and you want to change the fields name, just that one

fields name and imagine that struct has lots of fields, what you have to do is

you have to spell out all the fields in the, I think it's called codable keys,

to the protocol that you have to adopt, you know, to, to change or

override the key definitions.

And this package will give you an add-codable-path macro that you can tack on to your field just

to rename a single field without having to spell everything else out, I suppose.

Under the hood it just expands everything for you.

That's just the perfect use case for a macro, right?

Because that's a very tedious thing to do.

It reads much nicer because there's no noise.

It's really just about that one field that you're going to change.

Really nice.

It has a couple other tricks up its sleeves.

It allows nested paths.

So imagine you have a nested JSON struct and you want to pull out something that's like,

you know, drill down a couple of objects into the JSON file and then pull it up to the outer

layer, so to speak, and to assign it to a property there.

It can do that.

Also be the CodablePath.

And there's a Codable Compose attribute,

which is, it's difficult to describe.

It allows you to layer or compose different Codable types

into a common type.

So you can do a little refactoring

in case you're using object mapping onto JSON structs.

It's best to look at the documentation,

which is quite extensive, how that works.

So it's a really nice package

if you deal with these things in Codable,

and it's called Metacodable by Soumya Aranjanmahunt.

- Sounds like a package that's not so much revolutionary,

but it's just gonna save you some time, right?

- Exactly.

- So my first pack of recommendation also includes a macro.

It's both a very modern package

in that it only works with Swift 5.9,

but it's also a throwback to the Objective-C days,

because it is a macro that wraps an Objective-C function,

which is, I think, a nice little contrast between the two.

It's called AssociatedObject, and it's by,

I hope it's actually the second week in a row

that we've had a package by p-x9.

(laughing)

So we're back with another p-x9 package.

So AssociatedObject allows you to,

in a Swift extension, declare an additional property,

which is something that you can't currently do

'cause you can't declare anything that includes storage

and an extension.

And the way that it works is that it uses

the old Objective-C associated object API

to store and retrieve values out of memory.

And so then the implementation of it is really nice.

As an annotation on a property that you're adding

to whatever it is that you're extending,

you just say @associated object,

and you have to give it some memory management information

about whether it should retain it,

whether it's non-atomic, you know,

real throwback to the old objective C days.

But what it actually then does is it just lets you then,

on the next line, create a variable,

and that variable can have an initial value,

and it can do all the things that you would expect it to do.

And so it's, I don't know,

I really liked the idea of this package.

I'm not sure whether I'd put it into a project,

but I've certainly used Objective-C associated objects

many, many times, and they are very reliable.

- Right.

- So there's no reason you wouldn't,

but it also feels like you're bending the language

to something that it wasn't intended to do,

which is always kind of, ah, should you do that?

- Does it work on any type

or would it have to be a class, the extension?

- I think it has to be a class.

- Has to be a class, right.

Yeah, because it needs the Objective-C runtime

and that only, it probably adds

an Objective-C annotation, doesn't it?

- Yeah, exactly, yeah.

So, but I thought it was a curiosity and worth mentioning.

- Nice.

Right, well, I'm going to continue the theme

of macro packages.

And my second package is called Renamed by Joseph Duffy.

And this is another really nice package,

not a spectacular thing, but really neat.

It allows you to rename entities with a deprecation warning.

So effectively what it does, if you've renamed a property,

you can add this @renamed macro annotation

and spell out the old name that it had before.

And what it does then under the hood,

It creates a stub of the old property that forwards to the new one.

And the, and the stub has a deprecation annotation that tells users that still

use the old property, what new name it moved to, and, you know, none of that.

All of this is very easy to, to do manually, but if you have this, you

know, and you do a little refactoring, you don't need to sprinkle all this

extra stuff throughout, you can just add this one single thing to your property

and be done with it. And that's not just properties, that's also available for structs, classes,

enums, properties, functions, and more. So quite nice. That's called renamed by Joseph Duffy.

And not an Objective-C declaration in sight. My next package is one that we may end up using.

So it is a package called SwiftyESBuild,

and it's from the Tuist organization.

So Tuist is a package, an open source package

that will create and interact with Xcode projects.

So instead of having, like if you're building an iOS

or a Mac OS application,

and you've either got a very complex or a big team

working on a single Xcode project,

TUIST is a way that you can create an Xcode project

without actually checking an Xcode project

into your repository.

So you create the definition of an Xcode project

and then it generates one for you,

which is easier to work with in a big team

and has other advantages as well.

And one of the things that that organization has now added

is a new package called Swifty ES Build.

And it's actually part of a,

I think a pair of packages,

one that I think we will use and one that we won't use

because we don't use that technology.

So the first one is Swifty ESBuild

and the second one is Swifty Tailwind.

So ESBuild is the JavaScript build tool

that we use to generate all our front end assets,

JavaScript and CSS in the Swift package index.

And it's a tool that takes, for example,

TypeScript or SCSS or SAS files

or any of these kind of intermediate formats

that you have in front-end web world

and generates JavaScript and CSS

and minifies it and compresses it

and makes sure it's efficiently stored

and all the rest of it.

So that's ESBuild.

And the way that we currently build our front-end

is that we have two separate build processes.

We have the package build, which compiles the Swift code

and generates the vapor application.

And then we have a separate process

that runs as part of our deploy process,

which runs esbuild just in a Docker container

and generates the front end side of things.

And then the two things are combined

and we ship the application out to the servers

so it can be hosted.

What I want to play with is whether we can finally bring

those two build processes together using ESBuild.

So this is gonna be very specific to people doing web work.

I mean, I'm gonna say web work more than server-side Swift

because you could generate this for any web package.

This is not specific to vapor or server-side Swift

specifically. But it certainly is specific to web work. So maybe one slightly off to one side of

what most people will want, but it's something that I'm going to look at for the project.

Right, and this is a... I'm not sure if you've said it and I missed it. This is a build plugin,

right, that would run in the build phase or something?

You're right, I didn't say it and yes it is.

My final pick is... I'm sorry to say I'm going down that road again. It's called SwiftMath.

by Michael Griebling or Michael Griebling. I'm never sure if this person is of German heritage

and moved or is actually German. The name certainly looks German. And this is a bit

of a follow up to the package, Mars Jax Swift that I talked about, I guess at length in episode 27.

But this is a bit different, so I want to bring it up again, because this is a Swift

implementation of a LaTeX MATH renderer.

For those who may recall, the other package is actually using JavaScript's core and web

views to do the rendering, and this is based on a JavaScript LaTeX renderer.

The advantage of this one is that it's a Swift implementation, it claims to be significantly

faster than using web views. It's actually based on another package called iOS MATH, which is

in Objective-C, but this is a Swift translation of that, but the Readme specifically calls out

that package. It isn't just a straight up translation, it also has some claims to have

some bug fixes and improvements on top of it. So I think it sounds like Swift MATH is the successor

of iOS MATH. I think both support UIKit and AppKit. So, they aren't. It's called iOS MATH,

but I think it also supports macOS, the other one. But I only tried this one, and the really nice

thing is you can just stick it in a playground. So, you can use our feature, try in a playground,

which I get never tired of mentioning. But I just absolutely love it. I can throw it in there and

create a SwiftUI view and then have LaTeX expression rendered and this time it actually

doesn't pull in any extra stuff. It's all in a Swift package itself. So really nice.

And that opens up again of course the whole world of rendering all sorts of math expressions wherever

you use SwiftUI or UIKit or AppKit actually in that case. So really nice Swift math by

by Michael Gribbling, I'm going to go with the US version

of the name. (laughs)

- Well, I'm gonna say that that could potentially

be even more niche than my ES build plugin. (laughs)

- Well, here you go, you're coming here

for the niche package recommendations.

(laughs)

- The final, my final package recommendation

for this week is definitely not niche.

I think it fits in to almost, I would say,

any macOS or iOS package, sorry, application.

And it's a package called ReviewKit.

And again, it's another repeat author.

So it's by Cihat Gündüz and it's called ReviewKit.

And so there's been an API now for a long time

where you can request or offer the opportunity

for somebody using your application to fill in a review

or submit a star rating for your application

on the App Store.

And that API is quite unusual in Apple APIs

is that you can call it as many times as you would like to,

but it will only actually fire a certain number of times

within a 12 month period.

So if you call that function three times

within the first week of somebody using your application,

no matter how many times you call it in the future,

there is no, it will never display

to the person using your app.

And so a good practice way of offering

that kind of opportunity to review your application

is to present that prompt at carefully curated times.

And quite often, you know, it seems to be good practice

to say, well, when somebody has done something positive

in your application,

that's potentially a good time to ask them for a review.

So if they've just, if you write them a to-do application,

when somebody completes a to-do,

that's a, it's an opportunity that they've just done

something that they're happy with,

and they're done using your app at that point.

So they're probably gonna, the next step of,

after completing a to-do is probably to quit the application

or to move contexts to somewhere else.

So that's maybe a good opportunity

to present one of these reviews, review prompts.

And so the package allows you to record positive events

and define criteria.

So you can say, for example,

I'm looking for five positive events within the last 30 days

And it takes care of measuring those, keeping track of them.

And then if the criteria is hit, it will present

or it will attempt to present that review prompt for you.

And again, this is the kind of thing that it's,

there's no, as far as I know,

I haven't looked at the source code,

but there's nothing kind of terribly complex going on

behind the scenes, but it's the kind of thing

that you can just slot into your application

and get a better experience for the people using it.

And also for you, because these review prompts,

when presented correctly, can really make a big difference.

I've seen story after story after story of people saying,

as soon as I put this in,

the number of views just started to climb.

Like it just, people do review if you ask them to.

As long as you've made a good app, people do do it.

- Yeah, it's nice to have that taken care of, isn't it?

Really nice.

- It really is.

And talking of reviews,

So I actually had a piece of feedback this week

about the podcast, which was really nice.

And it was from somebody who was saying

that we should be a little more self-promotional

in the podcast, and I'm not gonna do this every time.

But it is just worth mentioning

that if you enjoy the podcast

or enjoy the package index, then sharing it,

liking the video, telling somebody about it,

I think more than the traditional like and subscribe,

I would much rather, if you enjoy it,

just tell somebody about it

that would really be appreciated by us

and is your opportunity to,

hopefully we're presenting this review prompt

after a positive experience.

- Yeah, let us know.

I'm curious what people think.

- Absolutely.

- Excellent.

- So until next time.

- Yeah, see you in two weeks.

- Absolutely, see you then.

- Bye-bye. - Bye-bye.

Creators and Guests

Dave Verwer
Host
Dave Verwer
Independent iOS developer, technical writer, author of @iOSDevWeekly, and creator of @SwiftPackages. He/him.
Sven A. Schmidt
Host
Sven A. Schmidt
Physicist & techie. CERN alumnus. Co-creator @SwiftPackages. Hummingbird app: https://t.co/2S9Y4ln53I
29: Are you saying that visionOS is more important than my sitemap?
Broadcast by