1
00:00:00,000 --> 00:00:04,800
Well, there was a blog post that I read this week, which I thought was quite

2
00:00:04,800 --> 00:00:07,280
interesting, which we may want to tackle first.

3
00:00:07,280 --> 00:00:13,680
It was from Ander Dobo who works with Flutter.

4
00:00:13,680 --> 00:00:17,120
I'm not sure whether he's on the Flutter team.

5
00:00:17,120 --> 00:00:20,280
I think he is by the look of his profile on the blog post.

6
00:00:20,280 --> 00:00:26,520
But it was a post around the progress of the Flutter and Dart package ecosystem,

7
00:00:26,520 --> 00:00:29,680
which post titles like that always catch my attention.

8
00:00:30,200 --> 00:00:31,800
At least in the last three years.

9
00:00:31,800 --> 00:00:39,640
And it was actually quite surprising how big the Flutter package ecosystem is to me.

10
00:00:39,640 --> 00:00:48,080
So Flutter's been around for, I don't know, several years now, more than five years, I would say.

11
00:00:48,080 --> 00:00:58,320
I think when it first came around, a lot of people kind of thought it was just after React Native did its thing.

12
00:00:58,560 --> 00:01:01,520
And fundamentally, it's actually quite a similar system.

13
00:01:01,520 --> 00:01:07,760
It's based on Dart instead of JavaScript, but JavaScript is the fundamental language behind Dart.

14
00:01:07,760 --> 00:01:08,600
I believe.

15
00:01:08,600 --> 00:01:23,800
And it's a cross-platform framework where you can build applications using different technologies for iOS and MacOS and other Apple platforms, as well as Android and all the rest of it.

16
00:01:25,360 --> 00:01:30,480
But then, I mean, I've paid attention to it a little bit over the years, but I've never used it.

17
00:01:30,480 --> 00:01:39,040
But I've not really been paying close attention, I don't think, because it has a huge package ecosystem.

18
00:01:39,040 --> 00:01:43,240
So we quite often do little quizzes here when we have stats like this.

19
00:01:43,240 --> 00:01:45,040
So it's time for a little quiz.

20
00:01:45,040 --> 00:01:46,200
Here we go.

21
00:01:49,600 --> 00:01:55,600
Total package ecosystem size right now in Dart, what would your guess be?

22
00:01:55,600 --> 00:01:58,920
We're about 7,000 on Swift at the moment.

23
00:01:58,920 --> 00:02:06,200
Yeah, I'm pretty sure it's more because these ecosystems tend to be really active.

24
00:02:06,200 --> 00:02:15,680
And if it's based on JavaScript, I guess there might be sort of, people might be conditioned into making smaller packages.

25
00:02:15,680 --> 00:02:17,480
So are we talking in size?

26
00:02:17,480 --> 00:02:19,040
Are we talking like number of packages?

27
00:02:19,280 --> 00:02:19,680
Sure.

28
00:02:19,680 --> 00:02:19,960
Yeah.

29
00:02:19,960 --> 00:02:20,360
Yeah.

30
00:02:20,360 --> 00:02:22,640
20,000?

31
00:02:22,640 --> 00:02:24,560
50,000.

32
00:02:24,560 --> 00:02:26,640
Okay, order of magnitude.

33
00:02:26,640 --> 00:02:27,560
I'll take the point.

34
00:02:27,560 --> 00:02:29,560
Yeah, order of magnitude is correct.

35
00:02:29,560 --> 00:02:37,800
But actually, more impressive than that is the rate of growth.

36
00:02:37,960 --> 00:02:52,360
So the post says that the ecosystem grew 26% during 2023, from 38,000 to 48,000 by the end of last year, which that's a significant growth.

37
00:02:52,360 --> 00:03:02,760
And also, so they have a package index site as well, which I believe is kind of an official package index site.

38
00:03:04,520 --> 00:03:14,880
Yeah, I'm not 100% sure on this, but I believe that, so on the homepage of pub.dev, which is their package index, it says supported by Google.

39
00:03:14,880 --> 00:03:30,080
So I'm not entirely sure whether that means it's a Google, like it's under development by Google, or whether it's a similar situation to the Swift package index, where it's supported by the language owner, in our case being Apple, in their case being Google.

40
00:03:31,720 --> 00:03:37,400
So, but I thought that was quite interesting, the amount of growth and also the amount of traffic.

41
00:03:37,400 --> 00:03:39,800
So they give some traffic stats on the blog post as well.

42
00:03:39,800 --> 00:03:45,760
700,000 monthly active users going to pub.dev, which...

43
00:03:45,760 --> 00:03:46,200
Interesting.

44
00:03:46,200 --> 00:03:52,080
But when you, did you say they grew how many, 26% year over year?

45
00:03:52,080 --> 00:03:53,960
26%, yeah.

46
00:03:53,960 --> 00:03:58,000
You know how much, I had the chance to look this up while you were talking.

47
00:03:58,000 --> 00:03:59,800
Do you know how much we grew year over year?

48
00:04:00,800 --> 00:04:03,160
That's a very, it's a very good question.

49
00:04:03,160 --> 00:04:04,000
I...

50
00:04:04,000 --> 00:04:06,080
It's a reverse quiz, this one.

51
00:04:06,080 --> 00:04:07,800
Yeah.

52
00:04:07,800 --> 00:04:14,360
Maybe it's because I'm closer to it, but it doesn't feel like our number of packages grew by 26%, but maybe I'm wrong.

53
00:04:14,360 --> 00:04:14,960
You're wrong.

54
00:04:14,960 --> 00:04:16,120
It's 27%.

55
00:04:16,120 --> 00:04:19,000
27%.

56
00:04:19,000 --> 00:04:19,840
That's amazing.

57
00:04:19,840 --> 00:04:23,080
Go Swift.

58
00:04:26,040 --> 00:04:30,160
I can tell you right now that we don't get 700,000 monthly active users on the package index.

59
00:04:30,160 --> 00:04:31,600
Oh, did you say 700,000?

60
00:04:31,600 --> 00:04:33,320
Because I thought you said 7,000.

61
00:04:33,320 --> 00:04:34,440
I thought, well...

62
00:04:34,440 --> 00:04:35,240
No, no, no.

63
00:04:35,240 --> 00:04:36,880
We could, we could beat 7,000.

64
00:04:36,880 --> 00:04:37,280
Yeah.

65
00:04:37,280 --> 00:04:39,200
Yeah.

66
00:04:39,200 --> 00:04:40,800
That's a, that's an enormous amount of traffic.

67
00:04:40,800 --> 00:04:43,680
And, and I don't know, it's, there's not a lot more to this post.

68
00:04:43,680 --> 00:04:52,040
But I thought that was really interesting seeing another package ecosystem really grow like this.

69
00:04:52,320 --> 00:04:56,640
They also give some great, some kind of favorites.

70
00:04:56,640 --> 00:05:04,120
They've got a Flutter Favorites program, which recognizes and helps developers discover the highest quality packages to consider using in their apps.

71
00:05:04,120 --> 00:05:18,200
And they've, so this is, I think, a little bit like the Swift Server Workgroup incubation program where packages get nominated to, to be part of this Flutter Favorites.

72
00:05:18,680 --> 00:05:27,720
And it says, right, Flutter Favorites are packages that have demonstrated exceptional quality, popularity, and community engagement, making them invaluable tools for Flutter development.

73
00:05:27,720 --> 00:05:35,800
So that's, I mean, I think that's, that's, it's great to see other package ecosystems thriving like this.

74
00:05:35,800 --> 00:05:47,400
And I thought it was worth highlighting to people who, here, who, you know, it's very easy when you're, when you're doing Swift all day to look inwards towards only what's happening within this community.

75
00:05:47,400 --> 00:05:49,160
And I thought this was worth mentioning.

76
00:05:49,160 --> 00:05:51,080
Yeah, it's definitely interesting.

77
00:05:51,080 --> 00:05:56,400
I mean, there aren't that many language ecosystems around, you know, that you can actually compare.

78
00:05:56,400 --> 00:06:05,560
And it's really nice to get these data points to see, you know, where, where Swift comes down to in terms of, you know, packages.

79
00:06:05,560 --> 00:06:07,200
And I was surprised by that.

80
00:06:07,200 --> 00:06:12,040
Well, then again, I'm not surprised because just way more JavaScript.

81
00:06:12,040 --> 00:06:14,240
Well, then again, there's lots of iOS developers, right?

82
00:06:14,240 --> 00:06:19,480
I mean, I wonder how big the developer populations are on either side.

83
00:06:19,480 --> 00:06:21,320
I guess there's more JavaScript, right?

84
00:06:21,320 --> 00:06:28,760
That is probably still, that's more people, but iOS is huge as well.

85
00:06:28,760 --> 00:06:30,560
So, interesting.

86
00:06:30,560 --> 00:06:30,840
It is.

87
00:06:30,840 --> 00:06:31,040
Yeah.

88
00:06:31,040 --> 00:06:31,600
Really interesting.

89
00:06:31,600 --> 00:06:43,280
I think iOS and Swift in general had a little bit of a reset in their package ecosystem with Swift Package Manager being around for a little while.

90
00:06:43,280 --> 00:06:47,920
But not possible to use within iOS and macOS projects for a while.

91
00:06:47,920 --> 00:06:56,400
And so there was a little bit of a kind of reset that we had in this ecosystem that, I mean, Flutter and Dart are not super old technologies,

92
00:06:56,400 --> 00:06:59,520
but I think they've been around a little longer than Package Manager.

93
00:06:59,520 --> 00:07:00,040
Yeah.

94
00:07:00,040 --> 00:07:01,760
Yeah, I mean, there's certainly that.

95
00:07:01,760 --> 00:07:12,640
Although you could also argue it's not a reset in the sense that it onboarded lots of, there are ways to onboard lots of Objective-C and even C packages, right?

96
00:07:12,640 --> 00:07:19,680
So it's sort of in quotes, cheating a bit by onboarding existing things as packages into the ecosystem.

97
00:07:19,680 --> 00:07:21,920
But then again, that's the appeal of it, right?

98
00:07:21,920 --> 00:07:32,320
There's just lots of tried and trusted legacy code that can be adopted and be used in Swift, which is great.

99
00:07:32,320 --> 00:07:34,800
So, yeah, interesting.

100
00:07:34,800 --> 00:07:41,280
One thing that they also do, which I quite liked was, they haven't actually published one for a couple of months,

101
00:07:41,280 --> 00:07:46,800
but I guess we've had Christmas and the holidays get in the way the last couple of months.

102
00:07:46,800 --> 00:07:52,640
They do a package of the week video, which looks to be very slickly produced.

103
00:07:52,640 --> 00:07:58,720
It's kind of got this animation with it, and someone goes into one of the packages and kind of talks about it.

104
00:07:58,720 --> 00:08:03,840
So there's obviously quite significant effort behind their package ecosystem.

105
00:08:03,840 --> 00:08:05,120
They're putting a lot of work into it.

106
00:08:05,120 --> 00:08:09,200
Oh, you're saying we need to beef up our YouTube game a bit?

107
00:08:09,760 --> 00:08:13,680
If we do, it's you doing it.

108
00:08:13,680 --> 00:08:17,840
I'll tell you that right now.

109
00:08:17,840 --> 00:08:22,000
No YouTube career in the near future.

110
00:08:22,000 --> 00:08:29,840
It's already the worst part of producing the podcast is making the YouTube video.

111
00:08:29,840 --> 00:08:33,360
That's with it being a still, right?

112
00:08:33,360 --> 00:08:36,400
Yeah, exactly.

113
00:08:36,400 --> 00:08:38,420
Nice.

114
00:08:39,380 --> 00:08:44,500
Well, we've also got a bit of a small piece of follow up as well.

115
00:08:44,500 --> 00:08:48,180
Last time we talked about the benchmarking package.

116
00:08:48,180 --> 00:08:51,860
And I thought I'd said it when I talked about it.

117
00:08:51,860 --> 00:08:55,380
But when listening back, I realized I actually didn't spell it out explicitly that

118
00:08:55,380 --> 00:09:01,220
this package allows benchmarking, a baselining of your benchmarks.

119
00:09:01,220 --> 00:09:05,940
So effectively doing the exactly the same thing as you can do in Xcode when you

120
00:09:06,660 --> 00:09:09,460
run your performance tests, your measurement tests there.

121
00:09:09,460 --> 00:09:11,940
You can, I think you can right click on the test and you

122
00:09:11,940 --> 00:09:15,860
can recall a baseline that then future runs are tested against.

123
00:09:15,860 --> 00:09:17,460
And you can do the exact same thing here.

124
00:09:17,460 --> 00:09:21,460
The advantage being it's now run via Swift PM.

125
00:09:21,460 --> 00:09:28,580
So you can run it through your normal test machinery there and on Linux as well,

126
00:09:28,580 --> 00:09:29,700
which is really nice.

127
00:09:29,700 --> 00:09:35,860
And if you are interested in seeing how that works, the Swift Neo package actually has

128
00:09:36,660 --> 00:09:40,580
a benchmark in it that use those baselines.

129
00:09:40,580 --> 00:09:41,620
So take a look at that.

130
00:09:41,620 --> 00:09:46,420
And thanks again for Joachim Hasseler for pointing this out to me after the podcast.

131
00:09:46,420 --> 00:09:47,060
Oh, interesting.

132
00:09:47,060 --> 00:09:47,560
Yeah.

133
00:09:47,560 --> 00:09:52,180
There's one other thing that I want to talk about this week before we get to

134
00:09:52,180 --> 00:09:53,460
package recommendations.

135
00:09:53,460 --> 00:10:00,020
And that is that there's, I think, what is quite a famous kind of warning to all

136
00:10:00,020 --> 00:10:02,420
software developers when talking about blogging.

137
00:10:03,300 --> 00:10:08,340
And all software developers, I think, are susceptible to the fact that when they

138
00:10:08,340 --> 00:10:11,860
decide to write a blog post, their first thought is, well, how am I going to write

139
00:10:11,860 --> 00:10:15,940
the blog software that I'll then write my blog post in?

140
00:10:15,940 --> 00:10:20,980
And there are so many pieces of blog software that have been started and then

141
00:10:20,980 --> 00:10:25,460
have one post written for them and then never, never been posted to again, that

142
00:10:25,460 --> 00:10:31,780
it's become a bit of a kind of a running joke that the first thing that a software

143
00:10:31,780 --> 00:10:35,380
developer will do when wanting to write a blog post is start to write blog software.

144
00:10:35,380 --> 00:10:39,780
Well, if you're a 10x programmer, you actually start writing an editor first, Dave.

145
00:10:39,780 --> 00:10:42,280
Right.

146
00:10:42,280 --> 00:10:46,500
So guess what I did yesterday?

147
00:10:46,500 --> 00:10:51,380
Well, I know you've already seen the pull request.

148
00:10:51,380 --> 00:10:56,580
I can't really fake surprise now because I've seen the commit history.

149
00:10:56,580 --> 00:10:57,780
You've seen the pull request.

150
00:10:57,780 --> 00:10:58,280
Yeah.

151
00:10:59,780 --> 00:11:03,220
So yes, I rewrote our blog yesterday.

152
00:11:03,220 --> 00:11:05,780
So there was a couple of reasons to do it.

153
00:11:05,780 --> 00:11:12,260
We're actually, we're in a period of trying to fix some of our SEO at the moment.

154
00:11:12,260 --> 00:11:15,780
We're having some, I think we've talked about it on the podcast before.

155
00:11:15,780 --> 00:11:23,140
And so we're in a bit of a, certainly I'm in a little bit of a mission to fix up

156
00:11:23,140 --> 00:11:25,700
several things and some of the stuff needed fixing on the blog.

157
00:11:25,700 --> 00:11:32,020
And actually we've been in a pretty terrible situation where the blog previews

158
00:11:32,020 --> 00:11:34,740
haven't been working for me.

159
00:11:34,740 --> 00:11:37,780
I don't know whether you run the previews Sven, I presume you don't.

160
00:11:37,780 --> 00:11:43,300
When you review the posts, I'm guessing you read them just the Markdown file, right?

161
00:11:43,300 --> 00:11:47,460
I run the, I spin up the server.

162
00:11:47,460 --> 00:11:52,260
So Visual Code has this thing where you can run a live server and I've often

163
00:11:53,620 --> 00:11:57,380
spun that up and read them in the rendered output.

164
00:11:57,380 --> 00:11:58,660
Oh, okay.

165
00:11:58,660 --> 00:11:59,380
Interesting.

166
00:11:59,380 --> 00:12:02,020
Now it's, I don't remember when I last did this.

167
00:12:02,020 --> 00:12:05,140
The last one, I don't, I'm sure I didn't.

168
00:12:05,140 --> 00:12:08,420
So I'm not sure if you're referring to this, this would have been broken.

169
00:12:08,420 --> 00:12:09,700
I think it might've been a little while.

170
00:12:09,700 --> 00:12:10,100
Yeah.

171
00:12:10,100 --> 00:12:10,660
Okay.

172
00:12:10,660 --> 00:12:10,980
Yes.

173
00:12:10,980 --> 00:12:11,220
Yeah.

174
00:12:11,460 --> 00:12:16,660
Our JavaScript environment needed some updates and it was fine.

175
00:12:16,660 --> 00:12:17,700
It was fine in production.

176
00:12:17,700 --> 00:12:22,260
Like when you run the final build of all the CSS and JavaScript, that's fine.

177
00:12:22,900 --> 00:12:24,340
But there are some issues with it.

178
00:12:24,340 --> 00:12:30,980
And also, you know, when we created that blog, in fact, I remember having the decision,

179
00:12:30,980 --> 00:12:34,820
discussion with you about the decision on whether we should even do a blog.

180
00:12:34,820 --> 00:12:36,740
And we didn't launch the site with a blog.

181
00:12:36,740 --> 00:12:41,460
And it was only after a little while that we added one.

182
00:12:41,460 --> 00:12:46,740
And I think it was a good decision, but I think it was, when we did it, we certainly,

183
00:12:46,740 --> 00:12:50,100
it wasn't a hundred percent sure that it would last forever.

184
00:12:50,100 --> 00:12:55,060
Like we needed to kind of prove the, do we actually post things to it?

185
00:12:55,060 --> 00:12:59,940
And while we don't post super often, we post often enough that I think it's worth having,

186
00:12:59,940 --> 00:13:02,420
like we use it semi-regularly.

187
00:13:02,420 --> 00:13:03,060
Yeah, definitely.

188
00:13:03,060 --> 00:13:03,560
Yeah.

189
00:13:03,560 --> 00:13:09,780
But of course, when it's outside of the main project, the kind of maintenance of it falls

190
00:13:09,780 --> 00:13:13,540
to one side because it's never the most important thing.

191
00:13:13,540 --> 00:13:18,500
So a couple of reasons to bring it in, we can give it a kind of update and a refresh.

192
00:13:18,500 --> 00:13:22,820
We also get to use all of the nice stuff that we have inside the package index.

193
00:13:22,820 --> 00:13:28,820
So we can actually bring in like the supporters, which I put down the side of the blog index

194
00:13:28,820 --> 00:13:29,540
and things like that.

195
00:13:29,540 --> 00:13:35,540
Obviously all of the markdown comes across and we're even still using the same markdown

196
00:13:35,540 --> 00:13:38,420
processor, which is John Sundells Inc.

197
00:13:38,420 --> 00:13:39,940
Project.

198
00:13:39,940 --> 00:13:45,940
So the rendering between the two, you know, one blog post to another should be identical.

199
00:13:45,940 --> 00:13:49,460
And in fact, I've tested it today and everything is looking great.

200
00:13:49,460 --> 00:13:54,420
Although it also made me find a whole load of problems that we had in the old blog posts,

201
00:13:54,420 --> 00:13:55,860
which I've kind of fixed up as well.

202
00:13:55,860 --> 00:14:02,500
So, yeah, now we have everything just under one URL.

203
00:14:02,500 --> 00:14:07,140
Everything's on swiftpackageindex.com, no more subdomains.

204
00:14:07,140 --> 00:14:13,540
There are obviously difficulties with going live with something like this, where you don't

205
00:14:13,540 --> 00:14:19,140
want to just abandon your old URLs because people will have linked to those blog posts.

206
00:14:19,140 --> 00:14:26,100
Even if it's just on social media, there will be traffic coming in through those old links.

207
00:14:26,100 --> 00:14:32,740
So I have a plan in place for setting up permanent redirects so that all the old traffic comes

208
00:14:32,740 --> 00:14:37,940
through and including, and this is something that it always, it's a little bugbear of mine

209
00:14:37,940 --> 00:14:45,380
that when people do change their blog software, if you don't redirect your RSS URL, then the

210
00:14:45,380 --> 00:14:49,700
people who were subscribed are suddenly no longer subscribed and they just don't know

211
00:14:49,700 --> 00:14:52,500
that they're not subscribed because it doesn't error or anything.

212
00:14:52,500 --> 00:14:59,140
So we're also going to redirect our RSS feed, of course, so that if you are subscribed,

213
00:14:59,140 --> 00:15:00,180
you will stay subscribed.

214
00:15:00,180 --> 00:15:04,100
Of course, if you'd like to update the URL, that's also fine.

215
00:15:04,100 --> 00:15:09,860
But that redirect will hang around forever.

216
00:15:09,860 --> 00:15:10,360
Nice.

217
00:15:10,360 --> 00:15:16,820
Is that going to be done via Cloudflare or do we run something on the existing, the old

218
00:15:16,820 --> 00:15:18,580
site, replace the old site with?

219
00:15:18,580 --> 00:15:25,300
Unfortunately, the old site was running on GitHub pages and GitHub page does not support

220
00:15:25,300 --> 00:15:26,580
redirects.

221
00:15:26,580 --> 00:15:29,540
So we could do it on Cloudflare.

222
00:15:29,540 --> 00:15:31,460
That was one thing I looked into.

223
00:15:32,100 --> 00:15:40,340
Unfortunately, it needs a page rule on Cloudflare and those, if you've ever had a cheap or free

224
00:15:40,340 --> 00:15:42,900
Cloudflare plan, they are very, very scarce.

225
00:15:42,900 --> 00:15:50,340
So instead, I'm going to use a site which I've used for my stuff for years and years

226
00:15:50,340 --> 00:15:50,820
and years now.

227
00:15:50,820 --> 00:15:55,940
It's called Netlify and they have a free plan, which is extremely generous.

228
00:15:56,660 --> 00:16:04,820
Like, for example, iOS Dev Directory runs and has always run off Netlify and several

229
00:16:04,820 --> 00:16:14,820
other sites that I run are all hosted there and they do support redirect files and they've

230
00:16:14,820 --> 00:16:21,620
been incredibly reliable for the years and years, easily more than five years that I've

231
00:16:21,620 --> 00:16:22,180
been using them.

232
00:16:22,740 --> 00:16:27,380
So they are great and we can just upload one little text file that says, here are a list

233
00:16:27,380 --> 00:16:31,700
of URLs, here are a list of new URLs and it'll serve that forever.

234
00:16:31,700 --> 00:16:31,940
Right.

235
00:16:31,940 --> 00:16:38,180
And because it's the blog subdomain, it can just point to that site and redirect to slash

236
00:16:38,180 --> 00:16:39,060
blog, I suppose.

237
00:16:39,060 --> 00:16:40,500
Exactly.

238
00:16:40,500 --> 00:16:40,900
Nice.

239
00:16:40,900 --> 00:16:42,180
Yeah, that's exactly it.

240
00:16:42,180 --> 00:16:48,580
And the main objective here is to get the SEO under one roof because those would be,

241
00:16:48,580 --> 00:16:51,460
or those currently are separate buckets, right?

242
00:16:51,460 --> 00:16:51,940
Exactly.

243
00:16:51,940 --> 00:16:52,420
Yeah.

244
00:16:52,420 --> 00:16:55,860
So I wouldn't say that's the primary reason.

245
00:16:55,860 --> 00:17:00,740
I think the other reasons were actually slightly more important, but when starting to look

246
00:17:00,740 --> 00:17:03,780
at some of the other reasons, it's like, well, I just need to, we just need to do this.

247
00:17:03,780 --> 00:17:07,300
And it didn't take that long.

248
00:17:07,300 --> 00:17:12,660
I started it kind of, I think, mid morning yesterday and it was pretty much done by the

249
00:17:12,660 --> 00:17:14,100
end of the day yesterday.

250
00:17:14,100 --> 00:17:21,220
Few little tweaks and cleaning up and stuff today, but it's not been a week's long project.

251
00:17:21,220 --> 00:17:25,940
So hopefully I can be forgiven for writing a blog.

252
00:17:25,940 --> 00:17:28,100
Nice.

253
00:17:28,100 --> 00:17:28,340
Yeah.

254
00:17:28,340 --> 00:17:30,180
I mean, I can see the appeal.

255
00:17:30,180 --> 00:17:32,260
It's much easier than to preview something.

256
00:17:32,260 --> 00:17:35,460
And the deployment process is the same one we use.

257
00:17:35,460 --> 00:17:41,620
The slight downside I see is that it's going to take a little longer to deploy because

258
00:17:41,620 --> 00:17:45,460
all our tests have to pass before we can merge.

259
00:17:45,460 --> 00:17:47,620
That's our rule.

260
00:17:47,620 --> 00:17:53,700
I mean, we could obviously, in the case of a blog, we could decide to short circuit that,

261
00:17:53,700 --> 00:17:55,620
but that's the only downside I can see.

262
00:17:55,620 --> 00:17:57,460
And that's not a huge problem, right?

263
00:17:57,460 --> 00:17:59,460
Five minutes versus 10 or something.

264
00:17:59,460 --> 00:18:03,380
So as a software developer, I also had to upgrade the functionality of our blog.

265
00:18:03,380 --> 00:18:11,780
And one thing that we get now is we get the ability to preview posts in the actual environment.

266
00:18:11,780 --> 00:18:18,100
So there's a YAML file in the repository, which is the index of all the posts, including

267
00:18:18,100 --> 00:18:20,180
summaries and things like that.

268
00:18:20,180 --> 00:18:29,620
And there's a published flag on there and published blog posts go to the live site and

269
00:18:29,620 --> 00:18:31,300
all blog posts go to the staging site.

270
00:18:31,300 --> 00:18:36,580
So we can publish the entire thing, check it over, have it live on staging.

271
00:18:37,780 --> 00:18:39,060
Both of us can be happy with it.

272
00:18:39,060 --> 00:18:44,820
And then that final pull request is simply changing the published flag from false to

273
00:18:44,820 --> 00:18:45,060
true.

274
00:18:45,060 --> 00:18:45,380
Yeah.

275
00:18:45,380 --> 00:18:46,020
Yeah.

276
00:18:46,020 --> 00:18:48,500
Even just locally previewing the thing, right?

277
00:18:48,500 --> 00:18:51,220
You know, we can just run the server locally.

278
00:18:51,220 --> 00:18:56,580
That's much easier than having to spin up that live server as I did in VS Code in times

279
00:18:56,580 --> 00:18:57,300
past.

280
00:18:57,300 --> 00:18:58,820
Yeah, that sounds great.

281
00:18:58,820 --> 00:19:03,460
The only other thing that was a concern, I think it will be okay, but we should probably

282
00:19:03,460 --> 00:19:06,580
just have a look when we go through the pull request.

283
00:19:07,300 --> 00:19:11,300
Certainly it's okay locally is it's no longer a static site.

284
00:19:11,300 --> 00:19:16,740
So the old site was a published site which runs and generates HTML that gets uploaded

285
00:19:16,740 --> 00:19:20,420
and no server code gets executed during blog visits.

286
00:19:20,420 --> 00:19:24,180
And of course, this is a dynamic site based on Vapor and all the rest of it.

287
00:19:24,180 --> 00:19:34,820
And so one thing that my initial attempt at creating this was to get the summary out of

288
00:19:34,820 --> 00:19:41,300
each file on disk, but to create the index page that was then opening up as many blog

289
00:19:41,300 --> 00:19:46,260
post files as we had on the system, which of course is already potentially a performance

290
00:19:46,260 --> 00:19:49,380
issue, but will only get worse as we publish more.

291
00:19:49,380 --> 00:19:56,180
So the index now is driven off one YAML file, and then it only opens the actual blog post

292
00:19:56,180 --> 00:19:58,500
file when you click into the page.

293
00:19:58,500 --> 00:20:03,540
But there is an additional kind of process that's happening when people view those blog

294
00:20:03,540 --> 00:20:09,700
posts, but I don't think it will have any kind of performance impact at all really.

295
00:20:09,700 --> 00:20:15,300
Shall we briefly talk about our production issues we had last week?

296
00:20:15,300 --> 00:20:16,500
Sure.

297
00:20:16,500 --> 00:20:19,380
And how it was all my fault.

298
00:20:19,380 --> 00:20:28,100
This was a joint effort because I laid the mine and you stepped on it.

299
00:20:28,100 --> 00:20:30,100
Yeah, okay.

300
00:20:30,100 --> 00:20:30,580
That's fair.

301
00:20:30,580 --> 00:20:31,140
That's fair.

302
00:20:31,140 --> 00:20:36,500
So, and as I said in our chat, that's why we have pull requests, right?

303
00:20:36,500 --> 00:20:37,940
And have reviews.

304
00:20:37,940 --> 00:20:43,460
It's one person opens up the pull request, the other reviews, and if something goes bad,

305
00:20:43,460 --> 00:20:48,740
yeah, both people were involved in getting that live.

306
00:20:48,740 --> 00:20:49,940
So that's the way it goes.

307
00:20:49,940 --> 00:20:52,180
So just very briefly, what happened?

308
00:20:52,180 --> 00:20:55,220
We had some, yeah, I mean, sort of downtime.

309
00:20:55,220 --> 00:21:04,260
We had a crash in production, which led to our system sometimes showing 500s in Cloudflare

310
00:21:04,260 --> 00:21:05,220
and timing out.

311
00:21:05,220 --> 00:21:09,060
And crashes have been really rare, actually.

312
00:21:09,060 --> 00:21:14,020
We've been blessed by very few crashes, and that's really thanks to Swift's focus on safety.

313
00:21:14,020 --> 00:21:19,700
And then of course, the first real issue we have with crashes is when we opt out of the

314
00:21:19,700 --> 00:21:20,980
safety mechanisms, right?

315
00:21:20,980 --> 00:21:27,460
Because what happened is we triggered a force unwrap where we had a try with a bang because

316
00:21:27,460 --> 00:21:29,380
we can't crash here.

317
00:21:29,380 --> 00:21:33,620
And the reason was, I'm just going to call it reason A, you know, there wasn't even a

318
00:21:33,620 --> 00:21:41,620
comment at the place where that force unwrap is, you know, we can't force unwrap here because

319
00:21:41,620 --> 00:21:42,260
of reason A.

320
00:21:42,260 --> 00:21:44,580
Famous last words.

321
00:21:44,580 --> 00:21:49,140
Of course, what happens is your program says, well, I'll just make you crash because of

322
00:21:49,140 --> 00:21:49,780
reason B then.

323
00:21:50,180 --> 00:21:51,140
[LAUGHTER]

324
00:21:51,140 --> 00:21:53,620
Which is a reason you didn't consider.

325
00:21:53,620 --> 00:21:54,820
And that's what happened here.

326
00:21:54,820 --> 00:22:01,300
It's just a great example where your exemptions hold for a very, very long time until they

327
00:22:01,300 --> 00:22:02,100
don't anymore.

328
00:22:02,100 --> 00:22:08,500
And a completely different thing blows up and then, you know, just goes through all

329
00:22:08,500 --> 00:22:11,300
the layers and nukes the service.

330
00:22:11,300 --> 00:22:19,700
What I really like is we have a-- if we consider this a problem that needs fixing, we have

331
00:22:19,700 --> 00:22:23,940
actually have a very easy way of finding all the places where we've been doing this, right?

332
00:22:23,940 --> 00:22:28,980
Like Swift is very nice in that you have to explicitly force this issue.

333
00:22:28,980 --> 00:22:33,620
So if we just search for try bang in the code base, we'd find all the places where we're

334
00:22:33,620 --> 00:22:35,780
doing this or similar things.

335
00:22:35,780 --> 00:22:40,820
We would have an easy time auditing where we're using unsafe mechanisms and then review

336
00:22:40,820 --> 00:22:43,620
if our assumptions still hold there.

337
00:22:43,620 --> 00:22:45,860
So that's a really nice thing about it.

338
00:22:45,860 --> 00:22:47,620
We explicitly force it.

339
00:22:47,620 --> 00:22:53,940
And when I say we, it was me who wrote that try bang and made the assumption that reason

340
00:22:53,940 --> 00:22:54,740
A holds.

341
00:22:54,740 --> 00:22:56,260
And reason A still holds.

342
00:22:56,260 --> 00:23:02,420
It's just that there's also reason B, which I wasn't aware of at the time I wrote this.

343
00:23:02,420 --> 00:23:08,820
And so that's really the main story here that sometimes your assumptions change.

344
00:23:08,820 --> 00:23:12,820
And yeah, that's how stuff goes wrong, right?

345
00:23:14,660 --> 00:23:21,780
Where this maybe ties into future Swift changes is that the reason this blew up is that the

346
00:23:21,780 --> 00:23:23,460
system is throwing under the hood.

347
00:23:23,460 --> 00:23:26,980
And I thought there's only one way it can throw, but there's actually a different way

348
00:23:26,980 --> 00:23:27,860
it can throw as well.

349
00:23:27,860 --> 00:23:34,580
I was expecting database errors due to a join failing to be the source of throws.

350
00:23:34,580 --> 00:23:37,060
And they can't happen because of the query we're running.

351
00:23:37,060 --> 00:23:39,540
They can't really throw and they never have.

352
00:23:39,540 --> 00:23:44,980
The problem is the other issue that can happen is that the payload that's being decoded can

353
00:23:44,980 --> 00:23:46,100
also have a decoding error.

354
00:23:46,100 --> 00:23:48,420
And that I did not consider at the time.

355
00:23:48,420 --> 00:23:55,460
And if you've been following Swift evolution, you may have seen that there's a proposal

356
00:23:55,460 --> 00:23:57,460
that's been accepted, which is typed throws.

357
00:23:57,460 --> 00:24:03,700
Right now, if you have throws, they're really just this error protocol and they're not typed

358
00:24:03,700 --> 00:24:04,820
in any way.

359
00:24:04,820 --> 00:24:10,260
So you can't really make very strong assumptions about what's throwing.

360
00:24:10,260 --> 00:24:16,660
Like I looked at, there's a call that's try and all I know, I'm going to get an error

361
00:24:16,660 --> 00:24:18,980
back and I can't really do much with it.

362
00:24:18,980 --> 00:24:26,740
With type throws, the underlying API could actually throw an error that is strongly typed,

363
00:24:26,740 --> 00:24:31,380
not just that error protocol, but really a, it could be, for instance, an enum that enumerates

364
00:24:31,380 --> 00:24:33,460
all the different error cases that happen.

365
00:24:33,460 --> 00:24:38,740
And if that had been the case, I'd have been alerted to all the different ways in which

366
00:24:38,740 --> 00:24:39,460
this can crash.

367
00:24:39,460 --> 00:24:44,820
And then I'd have seen, okay, this isn't just a database thing that might go wrong.

368
00:24:44,820 --> 00:24:46,420
Decoding might also go wrong.

369
00:24:46,420 --> 00:24:55,140
Now, I don't think APIs will actually adopt it in this case because that's a huge thing

370
00:24:55,140 --> 00:24:55,620
to do.

371
00:24:55,620 --> 00:25:01,060
And this is more, I think type throws in the motivation for the pitch has been more about

372
00:25:01,060 --> 00:25:04,340
very, very narrow use cases of this.

373
00:25:04,340 --> 00:25:10,740
You'd use this where you have a subsystem that really has only a handful of different

374
00:25:10,740 --> 00:25:14,260
error states that it's throwing where you really want to be sure that you gather all

375
00:25:14,260 --> 00:25:14,500
that.

376
00:25:14,500 --> 00:25:19,220
This call that I made has just way too many different things that might go wrong.

377
00:25:19,220 --> 00:25:23,700
Even if you just consider database things, there's just too many things that might come

378
00:25:23,700 --> 00:25:29,460
out of a database, especially because it's even different database technologies that

379
00:25:29,460 --> 00:25:31,380
could be under the hood, right?

380
00:25:31,380 --> 00:25:38,100
We're using Postgres, but other adopters of the API might be using SQLite and MySQL.

381
00:25:38,100 --> 00:25:42,100
So it would be really hard to enumerate all the error cases there.

382
00:25:42,100 --> 00:25:47,220
But I really wanted to raise this, that there are mechanisms in the future that might be

383
00:25:47,220 --> 00:25:49,380
helpful to address this problem.

384
00:25:49,380 --> 00:25:56,660
If you have a domain that has a very narrow set of errors that might happen, that it might

385
00:25:56,660 --> 00:26:01,540
really help make your decisions whether it's safe to force unwrap, because when you see

386
00:26:01,540 --> 00:26:06,980
it's an enum with four cases and you can ensure that those four cases are excluded or handled

387
00:26:06,980 --> 00:26:11,300
elsewhere, it will give you more confidence when you do the try bang.

388
00:26:11,300 --> 00:26:20,180
And I certainly shouldn't have looking at the result, but it's an interesting thing

389
00:26:20,180 --> 00:26:20,900
we saw.

390
00:26:20,900 --> 00:26:21,060
Yeah.

391
00:26:21,060 --> 00:26:26,980
Whenever you find yourself writing that comment, "This can't crash," it sets off a chain

392
00:26:26,980 --> 00:26:29,700
of events that will eventually lead to a late night.

393
00:26:29,700 --> 00:26:30,020
Yeah.

394
00:26:30,020 --> 00:26:31,940
Always bites you in the end.

395
00:26:31,940 --> 00:26:34,900
But the good news is we are back up and running.

396
00:26:34,900 --> 00:26:43,860
There was only a very, I don't know whether there was any actual 100% downtime.

397
00:26:43,860 --> 00:26:49,140
Certainly the site was slow for a little while and there were timeouts, but I don't think

398
00:26:49,140 --> 00:26:52,100
the site ever completely went offline because of it.

399
00:26:52,100 --> 00:26:54,100
No, I don't think so.

400
00:26:54,100 --> 00:26:58,580
Because what happened is that only a handful of pages actually led to the crash.

401
00:26:58,580 --> 00:27:00,660
So people would have to visit those pages.

402
00:27:00,660 --> 00:27:05,220
And then when that happened, a node was out for a minute.

403
00:27:05,220 --> 00:27:11,460
And the problem, the reason it was out for a minute is a reason that we're following

404
00:27:11,460 --> 00:27:11,860
up on.

405
00:27:11,860 --> 00:27:13,460
That's actually not our fault.

406
00:27:14,740 --> 00:27:19,460
Backtracing, unfortunately at the moment, is taking very long to render the backtrace.

407
00:27:19,460 --> 00:27:21,780
And that's a new change in 5.9.2.

408
00:27:21,780 --> 00:27:26,260
Previously, we actually would have crashed really quickly and probably people wouldn't

409
00:27:26,260 --> 00:27:33,060
have had issues with the site being down, except for those pages explicitly.

410
00:27:33,060 --> 00:27:38,420
The problem we actually incurred a little more, we actually hit timeouts was because

411
00:27:38,420 --> 00:27:43,700
of the backtracing taking so much time and locking out nodes, which was a bit unfortunate.

412
00:27:43,700 --> 00:27:46,900
And compounding with our self-inflicted issue.

413
00:27:46,900 --> 00:27:49,220
Lots to learn from.

414
00:27:49,220 --> 00:27:51,460
Right.

415
00:27:51,460 --> 00:27:54,180
Do we have any other news or shall we do some packages?

416
00:27:54,180 --> 00:27:55,300
I think it's package time.

417
00:27:55,300 --> 00:27:58,740
Why don't I kick us off this week?

418
00:27:58,740 --> 00:28:05,620
And I'll kick us off with a package called Vortex from Paul Hudson.

419
00:28:05,620 --> 00:28:12,420
So Vortex is, well, let's take the description direct from the readme.

420
00:28:12,420 --> 00:28:17,540
"Vortex is a powerful, high-performance particle system for SwiftUI, allowing you to create

421
00:28:17,540 --> 00:28:22,500
beautiful effects such as fire, rain, smoke, and snow in only a few lines of code."

422
00:28:22,500 --> 00:28:24,980
Now that's written like a true marketing professional, Paul.

423
00:28:24,980 --> 00:28:31,380
I feel the desire to fill my apps with particle effects after that.

424
00:28:31,380 --> 00:28:33,620
But it's actually looking great.

425
00:28:33,620 --> 00:28:44,820
So it uses, you can add a Vortex effect to any kind of SwiftUI view.

426
00:28:44,820 --> 00:28:49,460
So you can take, for example, a circle or a rectangle or something like that, or presumably

427
00:28:49,460 --> 00:28:56,660
even something like a text box or a label or something like that, and add particle effects

428
00:28:56,660 --> 00:29:03,460
to it defined by rain, fireworks, fireflies, magic, smoke, that kind of stuff.

429
00:29:03,460 --> 00:29:08,740
This is probably not the kind of thing that you're going to use every single day.

430
00:29:08,740 --> 00:29:17,780
But there are genuine uses for a package like this in iOS and macOS apps.

431
00:29:17,780 --> 00:29:25,300
The most common one is whenever the person using your application has just completed

432
00:29:26,180 --> 00:29:30,900
some kind of positive event, whether that's successfully doing the task that the app

433
00:29:30,900 --> 00:29:36,580
was designed to do, or whether it was purchasing your upgrade to an in-app purchase or something

434
00:29:36,580 --> 00:29:36,980
like that.

435
00:29:36,980 --> 00:29:44,100
I've quite often seen people throw up a load of confetti on the view and have it rain down.

436
00:29:44,100 --> 00:29:48,980
And I can imagine that you could use particle effects of all sorts.

437
00:29:48,980 --> 00:29:51,540
In fact, there is a confetti effect in this as well.

438
00:29:52,980 --> 00:29:59,300
But again, as you'd expect from Paul, it's a wonderfully written readme file, lots of

439
00:29:59,300 --> 00:30:03,860
example code, and I thought it was worth highlighting.

440
00:30:03,860 --> 00:30:04,980
Nice.

441
00:30:04,980 --> 00:30:06,340
Are there some examples?

442
00:30:06,340 --> 00:30:09,220
Can you preview what the package offers?

443
00:30:09,220 --> 00:30:09,460
Sure.

444
00:30:09,460 --> 00:30:13,780
I mean, there are animated GIFs on the readme file.

445
00:30:13,780 --> 00:30:17,140
That's probably the best way to get a sense of what it does.

446
00:30:17,140 --> 00:30:17,620
Right.

447
00:30:17,620 --> 00:30:18,180
Nice.

448
00:30:18,180 --> 00:30:20,180
And in fact, it looks like there is a demo.

449
00:30:20,740 --> 00:30:24,900
In fact, it says the repository contains a cross-platform sample project demonstrating

450
00:30:24,900 --> 00:30:25,700
all the presets.

451
00:30:25,700 --> 00:30:31,060
And I do believe you can actually make your own particles too, if you'd like to.

452
00:30:31,060 --> 00:30:31,700
Nice.

453
00:30:31,700 --> 00:30:36,980
If the default confetti is not confetti-like enough, then you can make your own confetti.

454
00:30:36,980 --> 00:30:37,860
Custom confetti.

455
00:30:37,860 --> 00:30:42,740
Yeah, I saw this flyby, but I hadn't actually looked at it.

456
00:30:42,740 --> 00:30:46,500
The iOS stuff, I expect you to pick those up.

457
00:30:49,300 --> 00:30:54,260
Even though it's been a while since I wrote an iOS app, but I think I still have more

458
00:30:54,260 --> 00:30:55,300
interest in it than you.

459
00:30:55,300 --> 00:30:57,220
Well, there's this newsletter, right?

460
00:30:57,220 --> 00:30:57,860
What's the title?

461
00:30:57,860 --> 00:30:59,300
I don't recall.

462
00:30:59,300 --> 00:31:06,340
I really messed up with several things when I named that newsletter.

463
00:31:06,340 --> 00:31:11,300
I didn't think it would still be going 13 years later.

464
00:31:11,300 --> 00:31:13,540
Right.

465
00:31:13,540 --> 00:31:19,620
My first package is called Language Detector by Ali Sheikhizadeh and Hadi Shargi.

466
00:31:19,620 --> 00:31:22,420
And this is an interesting package.

467
00:31:22,420 --> 00:31:24,820
It's a small package, 400 kilobytes.

468
00:31:24,820 --> 00:31:27,380
I looked it up because I couldn't believe it's that small.

469
00:31:27,380 --> 00:31:32,100
And it offers language detection for 110 languages, according to the README.

470
00:31:32,100 --> 00:31:32,980
I didn't actually count.

471
00:31:32,980 --> 00:31:35,540
I trust that metric.

472
00:31:35,540 --> 00:31:37,780
But it's a long list.

473
00:31:37,780 --> 00:31:43,460
And I was really curious how that could work without either making online requests to

474
00:31:43,460 --> 00:31:49,140
a service, it doesn't, or embedding some kind of dictionary language model.

475
00:31:49,140 --> 00:31:53,780
And that I would have expected to be quite large, or at least larger than 400k.

476
00:31:53,780 --> 00:31:56,660
So I've poked around a bit.

477
00:31:56,660 --> 00:32:00,100
And it wasn't hard because it's not a big package.

478
00:32:00,100 --> 00:32:05,780
But what it's doing under the hood, from what I understand, is doing frequency analysis

479
00:32:05,780 --> 00:32:07,700
on letters and syllables.

480
00:32:08,820 --> 00:32:15,140
So it just has small dictionaries in there with letters and syllables and then floats

481
00:32:15,140 --> 00:32:18,900
against them, which I presume are frequencies in strings.

482
00:32:18,900 --> 00:32:23,540
And that's why this whole thing is rather small, because these dictionaries are then

483
00:32:23,540 --> 00:32:24,260
small.

484
00:32:24,260 --> 00:32:25,780
I was curious how well that works.

485
00:32:25,780 --> 00:32:28,900
So I took a couple of paragraphs from some European newspapers.

486
00:32:28,900 --> 00:32:30,020
And it works.

487
00:32:30,020 --> 00:32:38,500
So in each case, and I tried the big ones, English, obviously, German, French, Spanish.

488
00:32:38,500 --> 00:32:40,900
And Italian, I think, as well.

489
00:32:40,900 --> 00:32:42,020
And it worked for all those.

490
00:32:42,020 --> 00:32:47,460
However, there's also, this spits out not just a single language, but like a little

491
00:32:47,460 --> 00:32:50,020
dictionary of language and then a number.

492
00:32:50,020 --> 00:32:52,900
And it's not documented, but I'm pretty sure the number is the confidence.

493
00:32:52,900 --> 00:32:56,260
And that was, they were quite close together.

494
00:32:56,260 --> 00:33:01,780
Sometimes maybe a bit too close for confidence if you really need this to be 100%.

495
00:33:01,780 --> 00:33:08,260
But I think it's a great package if you want to, for instance, you know, you have a post,

496
00:33:08,260 --> 00:33:12,580
imagine you have a Mastodon client and Mastodon allows you to set the language you're posting

497
00:33:12,580 --> 00:33:13,300
in.

498
00:33:13,300 --> 00:33:18,500
And that might be something you toss in there where you give, you pre-configure the selection.

499
00:33:18,500 --> 00:33:20,580
You know, it's a low cost thing to do.

500
00:33:20,580 --> 00:33:23,780
Even if it's wrong, it's not terrible.

501
00:33:23,780 --> 00:33:25,140
And it might be a good starting point.

502
00:33:25,140 --> 00:33:26,740
It might get lots of guesses right.

503
00:33:26,740 --> 00:33:32,500
So I think if your goal is to get a good hit rate on your guesses, but you don't need 100%,

504
00:33:32,500 --> 00:33:36,500
and you don't need, you know, don't want to ship a huge library of stuff, I think that's

505
00:33:36,500 --> 00:33:37,780
a great package to try.

506
00:33:38,660 --> 00:33:39,540
And give this a spin.

507
00:33:39,540 --> 00:33:44,340
- And just a nice, it's always nice to prove that you don't always need AI, right?

508
00:33:44,340 --> 00:33:45,700
- Exactly.

509
00:33:45,700 --> 00:33:48,980
Yeah, that's why I was really curious if it's something like that.

510
00:33:48,980 --> 00:33:55,860
I mean, obviously, you know, there's lots of quality in your estimates you can gain

511
00:33:55,860 --> 00:33:59,140
by throwing more at it, but sometimes you don't need it, right?

512
00:33:59,140 --> 00:34:03,300
The quick thing, even though you, there's a trade-off, right?

513
00:34:03,300 --> 00:34:07,140
You have a lower footprint and faster response, immediate thing.

514
00:34:08,100 --> 00:34:12,020
For, you know, maybe just 80% hit rate or something like that.

515
00:34:12,020 --> 00:34:17,220
I don't know what it actually is, but it's certainly worth trying and giving it a look.

516
00:34:17,220 --> 00:34:18,660
- That's great.

517
00:34:18,660 --> 00:34:19,700
Sounds interesting.

518
00:34:19,700 --> 00:34:28,580
My next package is by Kevin Mullins, and it's a package called Grace Language.

519
00:34:28,580 --> 00:34:35,620
And as I was preparing for today's podcast and thinking about how to talk about the

520
00:34:36,580 --> 00:34:39,860
engineering of a blog system that I did yesterday,

521
00:34:39,860 --> 00:34:49,140
this rings a bell as well in that if you want to allow plugins or some kind of scripting

522
00:34:49,140 --> 00:34:54,740
inside your iOS language, your iOS or Mac application, what's the first thing you do

523
00:34:54,740 --> 00:34:56,660
is you design your own language first, right?

524
00:34:56,660 --> 00:34:58,820
- Right after the editor, yep.

525
00:34:58,820 --> 00:35:02,500
- I'm not sure, yeah, exactly.

526
00:35:02,500 --> 00:35:06,740
I'm not sure that that's how this came about, but it is a new language called Grace,

527
00:35:06,740 --> 00:35:13,540
and it is apparently a Turing-complete scripting language written in Swift that can be used

528
00:35:13,540 --> 00:35:15,700
in applications that are then written in Swift.

529
00:35:15,700 --> 00:35:24,820
So it is, the language itself has enumerations and structs and functions and things like that.

530
00:35:24,820 --> 00:35:30,740
I didn't spot anything in the readme about it being object-orientated.

531
00:35:30,740 --> 00:35:33,940
There's certainly no definitions of classes or anything like that.

532
00:35:33,940 --> 00:35:39,700
It may just be a kind of, what do they call them, procedural language.

533
00:35:39,700 --> 00:35:50,260
But certainly the syntax looks nice enough, and you can very easily bring up a Grace runtime

534
00:35:50,260 --> 00:35:56,660
inside a Swift environment and run scripts or other code that's been written in this Grace

535
00:35:56,660 --> 00:35:57,460
language.

536
00:35:57,460 --> 00:36:04,500
So it's the kind of thing, I know a lot of applications, when they look for a scripting

537
00:36:04,500 --> 00:36:09,060
language like this, I think Lua is quite popular, isn't it?

538
00:36:09,060 --> 00:36:10,820
- Yeah, you see that pop up a lot.

539
00:36:10,820 --> 00:36:17,460
I think a lot of that is due to our World of Warcraft using it as its scripting language.

540
00:36:17,460 --> 00:36:18,100
- It did, yeah.

541
00:36:18,100 --> 00:36:19,140
I believe it still does, yeah.

542
00:36:19,140 --> 00:36:20,580
- Yeah, well, yeah, certainly, yeah.

543
00:36:20,580 --> 00:36:22,420
Interesting.

544
00:36:22,420 --> 00:36:23,860
So are there any interfaces?

545
00:36:23,860 --> 00:36:25,780
How would you use that?

546
00:36:25,780 --> 00:36:29,620
Is it just for computations or can it actually interface into the system back, you know,

547
00:36:29,620 --> 00:36:33,700
like calling, you know, dialogues or shortcuts or stuff like that?

548
00:36:33,700 --> 00:36:35,860
- That is a really great question.

549
00:36:35,860 --> 00:36:38,340
Really, really great question.

550
00:36:38,340 --> 00:36:39,220
- Here we go.

551
00:36:39,220 --> 00:36:43,220
- I don't know.

552
00:36:43,220 --> 00:36:46,020
Let me have a quick look.

553
00:36:46,020 --> 00:36:49,620
In fact, I was just scrolling up and down to see if I could see that.

554
00:36:49,620 --> 00:36:51,780
I can't.

555
00:36:51,780 --> 00:36:53,620
Although maybe I can.

556
00:36:54,500 --> 00:37:00,180
It keeps, a lot of the examples call app print, which I wonder if that's calling back to the

557
00:37:00,180 --> 00:37:01,700
host language.

558
00:37:01,700 --> 00:37:06,980
I would recommend that if this is interesting to you, that you go to the readme and give

559
00:37:06,980 --> 00:37:08,820
it a thorough read, which is something I didn't do.

560
00:37:08,820 --> 00:37:10,580
- Nice.

561
00:37:10,580 --> 00:37:15,320
Nice.

562
00:37:15,320 --> 00:37:21,940
Right, my second pick is called Versioned Codable by Jonathan Rothwell.

563
00:37:22,740 --> 00:37:31,220
And this is a really nice package, which one I probably would use if I had a use case or

564
00:37:31,220 --> 00:37:32,740
might even have one in the future.

565
00:37:32,740 --> 00:37:36,900
So this is a pack to deal with versioning of codable types.

566
00:37:36,900 --> 00:37:39,140
And we all know that problem, right?

567
00:37:39,140 --> 00:37:43,940
We've defined a codable type in our application and we've saved some data.

568
00:37:43,940 --> 00:37:47,780
And then we want to change that codable type.

569
00:37:47,780 --> 00:37:53,860
And we have data on disk or worse, some elsewhere, users have it.

570
00:37:53,860 --> 00:37:59,140
There are other services that use it and we are kind of stuck, right?

571
00:37:59,140 --> 00:38:01,460
If we change the type, we can't decode the old data.

572
00:38:01,460 --> 00:38:07,780
We want to change it because that's just the thing you want to do.

573
00:38:07,780 --> 00:38:10,740
You have no requirements, stuff like that.

574
00:38:10,740 --> 00:38:11,620
What do you actually do?

575
00:38:12,900 --> 00:38:17,940
And if you've worked with database systems, you've likely come across this concept there,

576
00:38:17,940 --> 00:38:24,900
which is called migrations, where for every change in data format, you have a system that

577
00:38:24,900 --> 00:38:32,660
migrates your data and then allows you to interface with it and write it and read it again.

578
00:38:32,660 --> 00:38:38,100
You know, like if there's a new field, if you have a field change or you remove a field,

579
00:38:38,100 --> 00:38:42,100
you have these migrations where you migrate your data over.

580
00:38:42,100 --> 00:38:46,260
And versioned codable does something similar for your codable types.

581
00:38:46,260 --> 00:38:53,540
And it works the way that each type, each version of your type is represented by a codable struct,

582
00:38:53,540 --> 00:38:55,060
just a plain old codable struct.

583
00:38:55,060 --> 00:38:58,660
And then you adopt a versioned codable protocol.

584
00:38:58,660 --> 00:39:06,740
And what this does, you declare what the previous version is, and then you define an initializer to

585
00:39:06,740 --> 00:39:10,180
instantiate that new type from the old type.

586
00:39:10,180 --> 00:39:14,420
And that then allows the system to lift up.

587
00:39:14,420 --> 00:39:18,980
If it encounters an older version, it goes through the chain until it arrives at the

588
00:39:18,980 --> 00:39:21,700
latest version or whichever version you actually want to decode.

589
00:39:21,700 --> 00:39:24,900
You don't need to, you can decode any version along the chain.

590
00:39:24,900 --> 00:39:31,380
But what you effectively set up is a sort of linked list of versions and whichever version

591
00:39:31,380 --> 00:39:38,420
you have, you know, goes into the chain and then, you know, you just keep on migrating

592
00:39:38,420 --> 00:39:41,700
them forward until you end up at the place where you want to be.

593
00:39:41,700 --> 00:39:45,780
It's really nice, a very simple interface, very obvious how you would use it.

594
00:39:45,780 --> 00:39:49,620
A nice readme and documentation to explain how that works.

595
00:39:49,620 --> 00:39:55,780
It also works in a playground, so you can just fiddle around with it there, see how that works.

596
00:39:55,780 --> 00:40:03,060
And a really nice thing that the author, Jonathan, has laid out that there's a bit of boilerplate

597
00:40:03,060 --> 00:40:03,220
there.

598
00:40:03,220 --> 00:40:09,460
It's not a huge amount, but I think he's planning to use macros to even do away with some of

599
00:40:09,460 --> 00:40:09,780
that.

600
00:40:09,780 --> 00:40:14,820
So this looks like a really nice package if you have the need for a versioning of codable

601
00:40:14,820 --> 00:40:15,060
types.

602
00:40:15,060 --> 00:40:15,780
>> That sounds great.

603
00:40:15,780 --> 00:40:16,980
>> I give it a look.

604
00:40:16,980 --> 00:40:19,620
Version Codable by Jonathan Rothwell.

605
00:40:19,620 --> 00:40:20,820
>> Very good.

606
00:40:20,820 --> 00:40:25,220
So I think that's probably enough packages for today.

607
00:40:25,220 --> 00:40:26,180
>> I think it is, yeah.

608
00:40:26,180 --> 00:40:33,540
>> So yet again, we come to the end of another episode and we'll be back in a couple of weeks

609
00:40:33,540 --> 00:40:38,740
with some more news, hopefully less news about crashing and less news about writing our own

610
00:40:38,740 --> 00:40:44,340
blog engines and more news about the wonderful other projects that we're going to embark on

611
00:40:44,340 --> 00:40:45,060
this year instead.

612
00:40:45,060 --> 00:40:47,300
>> Absolutely enough with the crashes.

613
00:40:47,300 --> 00:40:48,980
See you in two weeks.

614
00:40:48,980 --> 00:40:49,380
Bye bye.

615
00:40:49,380 --> 00:40:50,180
>> Exactly.

616
00:40:50,180 --> 00:40:51,380
See you then.

617
00:40:51,380 --> 00:40:52,340
Bye bye.