1
00:00:00,001 --> 00:00:06,720
just anything to keep the air moving a little. It's not often that we have to,

2
00:00:06,720 --> 00:00:13,280
that I complain of hot weather in the UK, but it's almost 30 degrees in here today,

3
00:00:13,280 --> 00:00:20,800
so it's not very pleasant. Speaking of temperatures and 30 degrees, I finally found a

4
00:00:22,000 --> 00:00:29,440
reason why Fahrenheit is better than Celsius. So is this the John Gruber thing? Because

5
00:00:29,440 --> 00:00:36,320
he was the one that convinced me, actually. Oh God, no, no, no, no. He has no standing.

6
00:00:36,320 --> 00:00:45,600
The reason is, I have the calendar and weather widgets on my watch next to each other, and I keep

7
00:00:45,600 --> 00:00:50,800
looking at my watch and I think, "Damn it, it's the 19th already. It's the 20th already in the

8
00:00:50,800 --> 00:00:54,640
month." I thought we only just had the start of the month, and I keep looking at the temperature.

9
00:00:54,640 --> 00:01:00,320
And if this was Fahrenheit, that probably, that problem wouldn't happen around here where it

10
00:01:00,320 --> 00:01:06,320
hardly ever hits zero degrees. So it'd always be 32 Fahrenheit and above. So,

11
00:01:06,320 --> 00:01:10,640
but I'm not going to switch anyway. I'm just going to have to train myself to-

12
00:01:10,640 --> 00:01:16,880
No, I'm not going to switch either because it's too much, it's impossible over here to switch

13
00:01:16,880 --> 00:01:22,320
into Fahrenheit because you'd be the only person using it. But I quite liked, this is years ago

14
00:01:22,320 --> 00:01:28,480
now, I quite liked John Gruber's explanation of it, which is that it's a more human scale

15
00:01:28,480 --> 00:01:37,360
for temperature. It is, you know, 100 degrees Fahrenheit is very hot and zero degrees Fahrenheit

16
00:01:37,360 --> 00:01:42,880
is extremely cold. And so in the middle, you've got the human range of temperature. And I quite

17
00:01:43,680 --> 00:01:48,720
like that, that spoke to me, actually. I thought that was quite a good way to think about temperature

18
00:01:48,720 --> 00:01:54,800
in a way that Celsius doesn't make sense like that, because zero Celsius is kind of cold,

19
00:01:54,800 --> 00:02:01,280
but it's not terribly cold. It's extremely cold. Like zero Celsius is like insanely cold.

20
00:02:01,280 --> 00:02:07,200
That's because you live in the South. No, it's because I just can't deal with cold. And then,

21
00:02:07,200 --> 00:02:13,040
you know, on the upper end, 40 is quite hot. So 40, 100, I mean, you can still,

22
00:02:13,040 --> 00:02:20,720
yeah, it's all right. I think Celsius is fine. I think it's fine too. But that's not why people

23
00:02:20,720 --> 00:02:27,360
are listening to the podcast, I'm pretty sure. Still not. So I think we should do a little bit of

24
00:02:27,360 --> 00:02:33,840
relevant news and things before we spend the entire time talking about temperature.

25
00:02:35,520 --> 00:02:39,600
I think there's just a couple of little updates on the project that are worth going over,

26
00:02:39,600 --> 00:02:50,800
first of all. Some good news. Our Swift 6.1 processing is finished. And the problems that

27
00:02:50,800 --> 00:02:58,800
we spoke about last time where we had the package list was letting packages that requires Swift 6.1

28
00:02:58,800 --> 00:03:04,640
in, but the project itself wasn't yet building them. And that kind of all that mess that we had

29
00:03:04,640 --> 00:03:11,920
with 6.1 is over. And not only is it over and we're accepting 6.1 packages, but all of the

30
00:03:11,920 --> 00:03:20,720
processing for compatibility with Swift 6.1 has now completed. So that's great news. And I'm sure

31
00:03:20,720 --> 00:03:27,600
you'll be happy to see the back of that problem as well. Oh, yeah. Yeah. That's a good result that

32
00:03:27,600 --> 00:03:35,760
we got that done. We also updated the Ready for Swift 6 page with the latest numbers for the

33
00:03:35,760 --> 00:03:42,560
Swift 6.1 processing. I was a bit surprised that there's still fluctuation there. I think it's

34
00:03:42,560 --> 00:03:48,560
still not settled down what's getting marked as... I think there's an influx of new things that get

35
00:03:48,560 --> 00:03:56,640
marked as errors with 6.1. I guess that's all just part of the process, right? Every time there's

36
00:03:56,640 --> 00:04:03,440
going to be a little bit less of that, I suppose, and we'll land in a place where the errors go down.

37
00:04:03,440 --> 00:04:08,720
Definitely saw an uptick, I think, in the number of packages without concurrency warnings. So that's

38
00:04:08,720 --> 00:04:17,200
definitely good. Yes. Well, there were a couple of reasons for that, right? And this is why that

39
00:04:17,200 --> 00:04:24,960
chart and that page in general is so difficult to kind of reason about because there are so many

40
00:04:24,960 --> 00:04:32,480
moving parts in that. There are the compiler updates. There are people adopting Swift 6

41
00:04:32,480 --> 00:04:38,000
and currency... Oh, sorry, Swift 6 language mode. And all of those things are moving forward

42
00:04:38,000 --> 00:04:44,720
independently of each other. And yet the chart only shows one number, which is always a little

43
00:04:44,720 --> 00:04:56,080
tricky to reason on that. But also included in the Swift 6.1 release was the fix for

44
00:04:56,080 --> 00:05:05,520
incorrectly identified concurrency errors. So there were some packages with Swift 6 that were

45
00:05:05,520 --> 00:05:10,320
showing concurrency errors, and we were reporting those concurrency errors. And we've talked about

46
00:05:10,320 --> 00:05:16,800
this on the podcast in the past. We were reporting those numbers correctly, but the numbers themselves

47
00:05:16,800 --> 00:05:23,600
were incorrect. And they are now fixed in 6.1. And so we're not only... It's actually three

48
00:05:23,600 --> 00:05:28,800
dimensions of movement now that you have that bug fix in there as well. You've got the compiler

49
00:05:28,800 --> 00:05:32,960
moving forward. You've got people's packages and source compatibility moving forward. And then

50
00:05:32,960 --> 00:05:40,000
you've got the fact that this bug was fixed, which correctly reports the number of issues

51
00:05:40,000 --> 00:05:47,360
in a package. So I wasn't surprised to see the total number of packages that have zero

52
00:05:47,360 --> 00:05:57,760
data race errors increase. But I think that second chart of the total errors is... I don't

53
00:05:57,760 --> 00:06:03,040
think that's providing a lot of very interesting information. - Yeah. One other wrinkle that I

54
00:06:03,040 --> 00:06:11,360
noticed, and I was a bit surprised by it, is that I tested a couple of packages which have

55
00:06:11,360 --> 00:06:20,480
zero errors, like both when I run it and as reported in 6.0, like when you compile with

56
00:06:20,480 --> 00:06:29,600
Swift 6.0, but do have warnings and errors that we correctly report as such in 6.1. So there seems

57
00:06:29,600 --> 00:06:38,480
to be something in 6.1 that raises new Swift 6 language mode errors that didn't before. And that

58
00:06:38,480 --> 00:06:45,920
was surprising to me. I thought in general, the expectation is that that isn't going to happen.

59
00:06:46,800 --> 00:06:54,640
But it looked legit. Like I looked at it, there were clearly warnings or errors issued by the

60
00:06:54,640 --> 00:07:02,320
compiler when I ran it on the packages. And I suppose the packages need to make adjustments.

61
00:07:02,320 --> 00:07:10,080
- Right. Yeah. The last little data point on this that I thought was worth pointing out is... So we

62
00:07:10,080 --> 00:07:17,680
have three lines on each of the charts on this Ready for Swift 6 page. And we've moved the kind

63
00:07:17,680 --> 00:07:22,320
of large link to this page off the home page on the Swift Package Index now, but it is still linked

64
00:07:22,320 --> 00:07:26,240
at the bottom of the page under Ready for Swift 6. And we'll also include a link to it in the show

65
00:07:26,240 --> 00:07:32,720
notes. But there are three lines on each of the charts, one for all packages, which actually kind

66
00:07:32,720 --> 00:07:39,600
of dwarfs the other two lines that we have, but you can untick the all packages line and see the

67
00:07:39,600 --> 00:07:44,320
other two lines that we have, which are all packages authored by Apple and all packages

68
00:07:44,320 --> 00:07:49,680
authored by the Swift Server Workgroup. And if you untick the all package line, you can see

69
00:07:49,680 --> 00:07:56,720
something quite interesting, which is that there is a very definite trend in those subsets of

70
00:07:56,720 --> 00:08:03,600
packages where people are obviously working on this problem. And both the Apple packages and

71
00:08:03,600 --> 00:08:09,360
the Swift Server Workgroup packages have doubled the number of packages that do not have any data

72
00:08:09,360 --> 00:08:15,120
race errors since the last run that we did. So not since the beginning, but since the last run

73
00:08:15,120 --> 00:08:23,600
that we did, which was in December 2024, it's jumped from 26 to 54 for the Apple packages and

74
00:08:23,600 --> 00:08:32,720
from 14 to 31 with the Swift Server Workgroup, which is, it shows that real work is happening

75
00:08:32,720 --> 00:08:38,800
there. And that subset, I think, gives a nicer picture of what's actually happening, which is

76
00:08:38,800 --> 00:08:44,800
that things are getting better. Yeah, definitely. Maybe we should say a word regarding that bigger

77
00:08:44,800 --> 00:08:52,240
gap between the last collected numbers. And that's mainly at the time when we learned about this

78
00:08:52,240 --> 00:08:57,440
reporting of false positives, we sort of stopped running this every two weeks because it felt like,

79
00:08:57,440 --> 00:09:02,320
you know, we had more and more reports of people saying, look, we don't have any warnings, but

80
00:09:02,320 --> 00:09:07,280
you're showing some. So we thought, well, it's actually not worth running it because the ratio of

81
00:09:08,000 --> 00:09:12,480
false reports seem to be quite high. And I think now we've sort of reached a point where

82
00:09:12,480 --> 00:09:19,840
it's enough to do this when there's, you know, new Swift point releases. So I, you know, Swift 6.2

83
00:09:19,840 --> 00:09:26,880
will presume, well, that's a full release. So, and I think that might be enough.

84
00:09:26,880 --> 00:09:33,920
Yeah, so we'll get a beta of that in a month or so at WWDC, I would imagine. Yeah.

85
00:09:33,920 --> 00:09:40,240
Yeah. The question is, do we even bother running the processing with a beta or do we just,

86
00:09:40,240 --> 00:09:42,960
you know, run it in the final version in the fall?

87
00:09:42,960 --> 00:09:51,360
The plan with those regular runs was always to do them for the majority of last year. That was our

88
00:09:51,360 --> 00:10:00,160
plan in terms of when we would run those kind of repeated runs to check for data safety. I don't

89
00:10:00,160 --> 00:10:09,280
know that the page is giving that much useful information anymore. I think it served its purpose

90
00:10:09,280 --> 00:10:18,880
last year and it's not useless, but it is of limited value given that when we do reprocess

91
00:10:18,880 --> 00:10:25,600
all those builds, it actually knocks our build infrastructure into kind of slow mode for just

92
00:10:25,600 --> 00:10:31,440
over a week's worth of processing time, which is quite a heavy toll to pay. And so if it was

93
00:10:31,440 --> 00:10:38,240
something that we could just do with no cost, not a monetary cost, but no cost in terms of the system,

94
00:10:38,240 --> 00:10:43,360
then I would say, yeah, sure. We, you know, we run it every month or something like that, but

95
00:10:43,360 --> 00:10:51,520
but it does have a cost. And so I think I'm more on the side of let's run it, let's take the

96
00:10:51,520 --> 00:10:59,040
figures when we do the Swift 6.2 release, but not during the betas. Yeah, yeah, exactly. I mean,

97
00:10:59,040 --> 00:11:06,560
I'm not sure how we did it last year. Do we adopt the betas during the WWDC week? I think we

98
00:11:06,560 --> 00:11:17,120
end up adding it early, right? We don't wait until September to add 6.2. So there'll be some...

99
00:11:17,120 --> 00:11:26,000
Yeah, but I could see us doing... If we add the beta over the summer, which we almost certainly

100
00:11:26,000 --> 00:11:32,960
will, then when the final 6.2 release comes, I can see us at that point doing a fresh set of data,

101
00:11:32,960 --> 00:11:39,600
but only that once. Yeah. Yeah, which we normally wouldn't. In the past, we haven't. When we switched

102
00:11:39,600 --> 00:11:44,960
from a beta to a release version, we didn't rerun all the builds, but this might be a reason to

103
00:11:44,960 --> 00:11:56,240
actually do it. It's sort of a week that it starts heating up the cluster. And we've also

104
00:11:56,240 --> 00:12:02,880
made a couple of changes to still prioritize new package additions. So the impact shouldn't be

105
00:12:02,880 --> 00:12:10,800
felt like... I mean, there is an impact, but it shouldn't punish new packages as much as it did

106
00:12:10,800 --> 00:12:16,000
in the past, where it really puts you at the end of the queue, potentially. And that's not the case

107
00:12:16,000 --> 00:12:24,080
anymore. Yeah. Yeah. We made that tweak to that, didn't we? Yeah. Yeah. So there we go. Swift 6.1

108
00:12:24,080 --> 00:12:32,320
is on the site. The other tiny little bit of news that just warrants mentioning is that... I don't

109
00:12:32,320 --> 00:12:36,960
remember whether we mentioned this last time or not. I think we may have done, which is that we

110
00:12:36,960 --> 00:12:47,040
had to temporarily disable package collection signing due to a fairly complex and quite boring

111
00:12:47,040 --> 00:12:54,240
set of circumstances, which we probably don't want to talk about here. But the good news is

112
00:12:54,240 --> 00:13:01,920
that that's all enabled and back up and working and package collections are, as they were, signed

113
00:13:01,920 --> 00:13:06,960
fully, able to be used without warnings in Xcode. So I thought that was just worth mentioning.

114
00:13:06,960 --> 00:13:13,360
Yeah. I did actually notice that they wouldn't work at all if they're unsigned in Xcode. So

115
00:13:13,360 --> 00:13:18,240
for that period of a few days, it might've been, I think it was less than a week in the end,

116
00:13:18,240 --> 00:13:24,640
it didn't actually work, but no one complained. So that's good news, I suppose.

117
00:13:25,920 --> 00:13:32,800
I get the feeling that package collections are not very well used. Certainly our package

118
00:13:32,800 --> 00:13:38,800
collections are not very well used. People may have their own set. I think one good use of

119
00:13:38,800 --> 00:13:44,960
package collections is if you have a set of packages in your company that are approved and

120
00:13:44,960 --> 00:13:52,560
you can adopt them without anybody raising an eye to them, then make a package collection of them.

121
00:13:52,560 --> 00:13:57,680
And they're right there in Xcode every time you need them. But keyword package collections,

122
00:13:57,680 --> 00:14:01,280
which is what we implemented, I don't get the sense that they're very well used at all.

123
00:14:01,280 --> 00:14:06,880
Yeah. Plus I think it would have only affected you if you wanted to add them fresh. I think

124
00:14:06,880 --> 00:14:16,960
if you had them already, it wouldn't have done any harm. So it wasn't a big deal, I think.

125
00:14:16,960 --> 00:14:19,680
Anyway, it's all fixed and back up and running. So that's great.

126
00:14:21,040 --> 00:14:28,400
Right. Well, in terms of non-project news, there's one thing that we could briefly talk about,

127
00:14:28,400 --> 00:14:36,400
and that is a tool that's been mentioned and announced on the Swift forums, and that's called

128
00:14:36,400 --> 00:14:43,200
Xtool. And I wanted to give a shout out to that. It's a tool to bring Xcode to Linux and Windows.

129
00:14:43,200 --> 00:14:50,080
That's what it says in the announcement. It's been around for a bit, I think, and it's now

130
00:14:50,080 --> 00:14:56,960
been formally announced. The idea is to be able to build and deploy iOS apps from non-Apple

131
00:14:56,960 --> 00:15:04,640
platforms. Now, there's one thing to be mindful of, and that's also been mentioned in the Swift

132
00:15:04,640 --> 00:15:13,280
forum thread where the project has been announced. There are licensing restrictions around how and

133
00:15:13,280 --> 00:15:20,640
where you use Apple's SDK. Now, I am not a lawyer, but you are potentially towing a legal line

134
00:15:20,640 --> 00:15:27,440
here when it comes to using this tool on non-Apple platforms. I think you're okay if you

135
00:15:27,440 --> 00:15:33,840
use it on Apple hardware, even if it's not Mac OS, so that might be all right.

136
00:15:33,840 --> 00:15:40,160
I think if in doubt, it would be useful to clarify the situation before you go off and

137
00:15:42,560 --> 00:15:46,800
invest hugely in this. I think you should be fine if you just want to try it out.

138
00:15:46,800 --> 00:15:54,320
But before you deploy CI and that sort of stuff, I think it's best to check, maybe wait if there's

139
00:15:54,320 --> 00:16:01,360
any clarification in the forum post. We'll obviously share the link. I haven't seen anything

140
00:16:01,360 --> 00:16:08,560
as of today being discussed there other than it being mentioned. You might be having licensing

141
00:16:09,600 --> 00:16:16,400
issues. But legal questions aside, the project looks really interesting. So, just the mere

142
00:16:16,400 --> 00:16:23,360
fact that it exists technically speaks, I think, to Swift becoming a stronger cross-platform

143
00:16:23,360 --> 00:16:31,040
language day by day. It's really exciting to see that this is even possible. And the project looks

144
00:16:31,040 --> 00:16:37,120
really nice. So, there's extensive documentation. There's actually a detailed doc C tutorial where

145
00:16:37,120 --> 00:16:44,720
it walks you through what you need to install. It's like brew, you brew install the thing,

146
00:16:44,720 --> 00:16:52,720
then you sign in to your Apple developer account, how you connect your device. And it's like,

147
00:16:52,720 --> 00:16:57,440
really, it talks about just plug your device into USB. There's no mention of this being a Mac or

148
00:16:58,240 --> 00:17:07,360
you needing Xcode. It really just is a CLI binary that you run. And I really love the fact that it's

149
00:17:07,360 --> 00:17:15,600
actually a command line interface. I do appreciate the GUI for something that I really know already,

150
00:17:15,600 --> 00:17:20,320
like as a shortcut or as a convenience for something that I understand and I know how it

151
00:17:20,320 --> 00:17:27,040
works. But I really find learning about something new, a command line interface is just fantastic

152
00:17:27,040 --> 00:17:32,240
because the representation of what the inputs and outputs are, are to me much clearer in text form.

153
00:17:32,240 --> 00:17:38,240
I find it much easier to see, all right, I type this and I get this back. And then I can replicate

154
00:17:38,240 --> 00:17:44,080
that locally. I find that much, much easier to do than watching a video or looking at screenshots

155
00:17:44,080 --> 00:17:49,280
and stuff. And I found that really nice that there's a tool now that does a lot of the things

156
00:17:49,280 --> 00:17:55,440
that Xcode does graphically. I mean, I know there's Xcode Build that probably also does that,

157
00:17:56,160 --> 00:18:00,800
but anyone who's ever interacted with Xcode Build's command line interface will probably agree

158
00:18:00,800 --> 00:18:10,160
that a proper Swift argument parser command line interface is likely more comfortable to use.

159
00:18:10,160 --> 00:18:17,440
So yeah, I think it's a really interesting project and I'm curious to see where this might lead.

160
00:18:17,440 --> 00:18:23,280
- I think there's a couple of things I want to mention here. I think one of the

161
00:18:25,600 --> 00:18:32,480
areas that is crying out for a tool like this is actually some of the cross-platform frameworks like

162
00:18:32,480 --> 00:18:41,760
Flutter and React Native, where you still have to do those final builds with Xcode. You can develop

163
00:18:41,760 --> 00:18:46,880
the software on any platform, but then you have to do the final build with Xcode on a Mac.

164
00:18:46,880 --> 00:18:54,400
And there is just no solution to that, apart from get a build machine, which is a Mac.

165
00:18:55,440 --> 00:19:03,760
Which for a certain segment of applications is a big disadvantage, not a big disadvantage for Apple,

166
00:19:03,760 --> 00:19:10,080
but a big disadvantage for the people who are using those tools. And there are a significant

167
00:19:10,080 --> 00:19:15,680
number of people and especially a significant number of companies, because as soon as you'd

168
00:19:15,680 --> 00:19:22,400
have to justify writing two separate apps, one for Android, one for iOS, then those cross-platform

169
00:19:22,400 --> 00:19:27,120
frameworks begin to look really tempting. And there's a lot of companies that use those

170
00:19:27,120 --> 00:19:34,000
cross-platform frameworks all over the place. So I think that segment of mobile development

171
00:19:34,000 --> 00:19:40,720
has been crying out for something like this, which is interesting to see what it will do to

172
00:19:40,720 --> 00:19:45,120
those technologies. And then the other thing that I think is worth mentioning is,

173
00:19:48,720 --> 00:19:55,600
and it has been announced because there was a post on the Swift blog in February by Owen Voorhees,

174
00:19:55,600 --> 00:20:03,520
which is the next Swift build tool, which is presumably again, going to come

175
00:20:03,520 --> 00:20:12,640
maybe even in a month's time at this month's WWDC. So that is the Swift build technology,

176
00:20:12,640 --> 00:20:19,200
which, and I haven't looked into this in great detail. So maybe if you have, correct me if I'm

177
00:20:19,200 --> 00:20:28,640
wrong here, but I believe that is effectively taking a lot of what Xcode build can do that

178
00:20:28,640 --> 00:20:37,120
Swift build can't do, but also that that is going to be a cross-platform build tool as well. Do you

179
00:20:37,120 --> 00:20:39,840
have any information on whether that's cross-platform? I think it is.

180
00:20:39,840 --> 00:20:46,880
I'm pretty sure it is. I don't know to what extent it will tackle the other things that Xcode

181
00:20:46,880 --> 00:20:54,400
build and Xcode do, right. And that Xtool does, you know, like the signing and the distribution

182
00:20:54,400 --> 00:21:00,240
part. That's what Xtool actually does. You can sign your application. You can, I think it also

183
00:21:00,240 --> 00:21:07,920
supports pushing the binary up. Obviously it does install on device, you know, that's the deploy

184
00:21:07,920 --> 00:21:12,480
part at the very least. It might not be the app store deploy part, although I think it also does

185
00:21:12,480 --> 00:21:20,480
that, but it certainly does the on device launching and interacting. I think it doesn't do debugging

186
00:21:20,480 --> 00:21:31,200
yet, but it's, you know, it's small steps. And I mean, in my mind there has to be, I understood

187
00:21:31,200 --> 00:21:38,080
this announcement of Swift build, this new Swift build to be the first steps in replacing what

188
00:21:38,080 --> 00:21:46,800
I understand as Xcode build, you know, like the Xcode build command and all the machinery in Xcode

189
00:21:46,800 --> 00:21:51,120
to build iOS applications, which is what you currently, you still need.

190
00:21:51,120 --> 00:21:59,200
I believe the intention of it is to replace both Xcode build and Swift build. I think it is a

191
00:21:59,200 --> 00:22:04,640
replacement for both of those tools. Yeah. Yeah. I mean, in my mind, sort of, it is an evolution

192
00:22:04,640 --> 00:22:10,320
of Swift build because I think you invoke, you probably end up invoking it exactly the same way.

193
00:22:10,320 --> 00:22:14,720
So for me, it's like Swift build version 2.0, whereas Xcode build is like very different,

194
00:22:14,720 --> 00:22:19,200
right? It's like a replacement, which is something entirely, well, entirely different. I mean,

195
00:22:19,200 --> 00:22:23,600
it's a command line interface, right? But still, if you, as I said earlier, if you've ever used

196
00:22:23,600 --> 00:22:28,400
Xcode build in earnest, you can tell it's like a very different tool. It's not, you know,

197
00:22:28,400 --> 00:22:33,920
a typical Unix tool in the way you provide parameters in the output that it gives,

198
00:22:33,920 --> 00:22:39,360
because it just inundates you with output. It's like, you don't know what's coming if you start,

199
00:22:39,360 --> 00:22:45,680
if you launch an Xcode build command, you're going to get lots of output. It's just very

200
00:22:45,680 --> 00:22:52,400
different. So I'm looking forward to what this development will bring. I think it's a very

201
00:22:52,400 --> 00:22:58,560
interesting project. And I, it was also on my list to talk about today. So it's good that the

202
00:22:58,560 --> 00:23:03,200
topic has come up. Shall we do some package recommendations?

203
00:23:03,200 --> 00:23:04,640
Yeah, let's do some packages.

204
00:23:04,640 --> 00:23:06,400
Why don't you kick us off this week?

205
00:23:06,400 --> 00:23:13,520
All right. My first pick is another beautiful UI related package by Rob Boehnke. It's called

206
00:23:13,520 --> 00:23:14,080
Redline.

207
00:23:14,080 --> 00:23:17,840
Oh, no, we're going to have potentially two.

208
00:23:20,320 --> 00:23:23,200
I thought we had a conflict today, but it wasn't this.

209
00:23:23,200 --> 00:23:32,160
Here we go. I think we're okay on the others, but we shall see. I just love this package. I mean,

210
00:23:32,160 --> 00:23:38,480
I keep mentioning that I don't do a lot of UI development, especially not these days. But if

211
00:23:38,480 --> 00:23:47,440
I was, this would definitely be something I'd use. What this does, it's a SwiftUI package that gives

212
00:23:47,440 --> 00:23:53,360
you modifiers that you can tack on to views to show spacing, position, and size information of

213
00:23:53,360 --> 00:23:59,840
those views in context with the surrounding views, size of the view itself. And it's just

214
00:23:59,840 --> 00:24:06,880
beautifully rendered. Imagine these springs and struts where you have the distance spaces and

215
00:24:06,880 --> 00:24:12,560
like beautiful, these round rec labels between them to show you what distance is between elements.

216
00:24:13,360 --> 00:24:19,680
Little size insets where it shows you what the size of the element is. It just looks beautiful.

217
00:24:19,680 --> 00:24:26,160
Look at the read menu. You immediately know what this is about and how to use the handful of

218
00:24:26,160 --> 00:24:33,120
modifiers there are. I think it's like spacing and position size. It'll be very obvious how that

219
00:24:33,120 --> 00:24:38,640
works. And it's just a beautiful package. And it's a dev package. Obviously, you're not going to ship

220
00:24:38,640 --> 00:24:46,000
this with it being enabled. So it's a perfect tool to drop into your project to use in your dev

221
00:24:46,000 --> 00:24:50,240
cycle. And then whenever you need to ship, obviously, it's not going to be present

222
00:24:50,240 --> 00:24:55,600
anyway. So it's one of those dependencies that are really super easy to adopt because

223
00:24:55,600 --> 00:25:01,280
they help you in your development. But they will never impact your shipping when stuff might be

224
00:25:01,280 --> 00:25:08,320
problematic if a package isn't maintained anymore or for whatever reason it doesn't build anymore.

225
00:25:08,960 --> 00:25:14,320
You just don't use it and you lose your ease of development, but you never put your

226
00:25:14,320 --> 00:25:21,680
shipping at risk. And I think it's just perfect. >> And I know you mentioned already the readme

227
00:25:21,680 --> 00:25:28,320
file there. But this readme file is the best example of a picture is worth a thousand words

228
00:25:28,320 --> 00:25:35,120
that I've ever seen. The readme file starts with a 20-word sentence that describes the package,

229
00:25:35,920 --> 00:25:40,080
which your eyes actually drawn over that because there is a huge screenshot immediately below it,

230
00:25:40,080 --> 00:25:45,280
which explains everything you would want to know about this package in one screenshot. It is

231
00:25:45,280 --> 00:25:52,320
brilliant. And as soon as I saw that, I thought, oh, what a great looking package. And then I

232
00:25:52,320 --> 00:25:58,000
investigated a little bit and had a look at the code example underneath it. And yeah, I agree.

233
00:25:58,000 --> 00:26:05,200
I agree with everything you just said there. I mean, Rob has made a lot of packages that we've

234
00:26:05,200 --> 00:26:13,120
recommended on this podcast. And so I don't think it's quite as many as your point three

235
00:26:13,120 --> 00:26:21,360
recommendations. But I think he's certainly up there with the potentially second place in terms

236
00:26:21,360 --> 00:26:27,360
of how many packages we've recommended there. But again, I have no hesitation from recognizing this

237
00:26:27,360 --> 00:26:33,120
as just a fantastic thing to check out. And as you say, it just has no downside because you're

238
00:26:33,120 --> 00:26:39,520
not going to ship it. So it's great. Yeah. Isn't Rob also the person or part of the team who

239
00:26:39,520 --> 00:26:47,360
developed an extensive animation UI library? Yeah. I recall seeing posts of his that are just

240
00:26:47,360 --> 00:26:53,120
beautiful. They show you. Yes. Like it's just fantastic UI work that that did you do you know

241
00:26:53,120 --> 00:26:58,160
what it's called? I can't recall the name. I think it was a commercial. I can't remember the name

242
00:26:58,160 --> 00:27:05,440
either. But you're right that that is the same Rob. Yeah. Right. There you go. Redline by

243
00:27:05,440 --> 00:27:08,560
Rob Boonker. Well, my first package is Redline. But no.

244
00:27:08,560 --> 00:27:17,600
Well, I'm going to put my so I thought we might have a clash today. So I'm going to do my

245
00:27:17,600 --> 00:27:23,360
my other potential clash next so that we both potentially get to do at least one unique one.

246
00:27:24,160 --> 00:27:29,680
So the package I'm going to talk about is called Harmonize by Peristreet Software.

247
00:27:29,680 --> 00:27:37,040
And the reason I thought we were going to have a clash is because you added this package to the

248
00:27:37,040 --> 00:27:41,600
index. It wasn't the author who added it. It was it was you that added it. And so I thought the

249
00:27:41,600 --> 00:27:47,120
reason you'd added it was because it was on your shortlist. Was it? It is on my extended list. I

250
00:27:47,120 --> 00:27:52,960
think it was announced on the Swift forums and I sort of tend to if I see something,

251
00:27:53,600 --> 00:27:59,360
I sort of plug it in if we don't have it already. I thought this was interesting. So the basic idea

252
00:27:59,360 --> 00:28:05,600
here is I'm not I'm not sure I actually agree with the official description. The official

253
00:28:05,600 --> 00:28:10,480
description is that it's a modern linter for Swift that allows you to write architectural

254
00:28:10,480 --> 00:28:16,560
lint rules as unit tests. I can see why they would describe it as a linter, but I think it's

255
00:28:16,560 --> 00:28:23,280
a little bit different to a certainly the way that I think about a linter. What it allows you

256
00:28:23,280 --> 00:28:32,720
to do is encode rules in your unit tests for how your project is structured. So, for example,

257
00:28:32,720 --> 00:28:39,360
if you wanted to make sure that every view model class that you had was inherited from a base view

258
00:28:39,360 --> 00:28:47,440
model, you could write an assertion in a unit test that checks that in your source code. And so it

259
00:28:47,440 --> 00:28:57,360
allows you to encode your kind of organizational structure, your development structure into rules

260
00:28:57,360 --> 00:29:05,760
in your code base and and then have that run as part of your CI so that you never get that problem

261
00:29:05,760 --> 00:29:13,040
of forgetting to do something that might not present itself as a problem immediately, but might

262
00:29:14,000 --> 00:29:18,560
present itself further down the line when you've realized you haven't, you know,

263
00:29:18,560 --> 00:29:27,200
followed one of these rules that you have. And it allows you to basically get references into

264
00:29:27,200 --> 00:29:37,200
your code and get lists of your classes in a very easy way and then write logic into those

265
00:29:37,200 --> 00:29:43,600
unit tests. And I thought that was quite a unique idea. I hadn't seen anyone do anything like that

266
00:29:43,600 --> 00:29:52,960
before. I believe there is a project originally written by Orta Throx, who was one of the founders

267
00:29:52,960 --> 00:30:00,400
of CocoaPods called Danger, which is the same kind of thing, which is you're encoding your

268
00:30:00,400 --> 00:30:08,560
best practices into a separate process that you can then enforce with continuous integration.

269
00:30:09,760 --> 00:30:15,200
And that's the only thing like this that I've seen before. But I thought this was worth mentioning

270
00:30:15,200 --> 00:30:20,800
because of how relatively unique it is, even though you can't have a relatively unique thing.

271
00:30:20,800 --> 00:30:31,680
- Yeah. Yeah, I found that really interesting too. I was sort of wondering if there's an added

272
00:30:31,680 --> 00:30:37,200
value in having it as a Swift test. I mean, obviously it's easy to run, right? Because

273
00:30:37,200 --> 00:30:42,480
you know how to run tests already, or you should. And then there's very little to learn, right? How

274
00:30:42,480 --> 00:30:47,520
do you, you know, don't actually instruct anyone where we have these rules, make sure you run them.

275
00:30:47,520 --> 00:30:51,360
It's almost harder not to run them, right? If you run all the tests, it's going to be a part of it.

276
00:30:51,360 --> 00:30:52,080
- Of course.

277
00:30:52,080 --> 00:30:56,960
- So in that sense, I think that's a really strong argument to have it that way. I wonder if there's

278
00:30:56,960 --> 00:31:04,560
sort of rules that you can't do that way, because I suspect, I mean, it has to run like something

279
00:31:04,560 --> 00:31:11,120
like Swift syntax to understand your code. But I think all the other linters pretty much do the

280
00:31:11,120 --> 00:31:16,960
same, right? I mean, I'm not sure if they all use Swift syntax. I think some of them are regx-based,

281
00:31:16,960 --> 00:31:25,440
but I wonder if that's equivalent, right? If just the fact that the examples are Swift syntax-based

282
00:31:25,440 --> 00:31:30,400
doesn't mean they would have to be, right? I would imagine even if it was, if you wanted

283
00:31:30,400 --> 00:31:36,000
regx-based rules, it is probably also possible to write those in this mechanism. I'm not sure

284
00:31:36,000 --> 00:31:41,360
if they have support for that or if that's something they consider, or if that's a limitation,

285
00:31:41,360 --> 00:31:47,600
I'd be curious about that because if it's not, I think that's the best argument to use that over

286
00:31:47,600 --> 00:31:53,440
the others, because you have so much less explaining to do, right? And maintaining to do

287
00:31:53,440 --> 00:31:58,000
in terms of how do you actually, you know, run this extra stuff. And I think that's a really

288
00:31:58,800 --> 00:32:01,600
potentially compelling argument for that sort of tool.

289
00:32:01,600 --> 00:32:08,000
- I don't know how it handles things. I mean, it probably doesn't is the truth of it, but

290
00:32:08,000 --> 00:32:15,760
handles things outside of code, basically. So one of the things that Danger can do is make sure,

291
00:32:15,760 --> 00:32:21,040
for example, that you've added an entry in a changelog when you submit a pull request,

292
00:32:21,040 --> 00:32:28,240
that kind of thing that is outside of your code base, but still very important. If your

293
00:32:28,240 --> 00:32:32,880
organization has chosen to make that a rule that you must add a line in the changelog when you

294
00:32:32,880 --> 00:32:39,360
write a pull request, then encoding that in something that can get run through CI is difficult.

295
00:32:39,360 --> 00:32:49,360
And so I think Danger probably has a broader set of uses, but as I say, I thought this was

296
00:32:49,360 --> 00:32:54,240
worth mentioning. And this probably does stuff that you would struggle to do with Danger. Like

297
00:32:54,240 --> 00:32:59,920
you say, you're not relying on regular expressions. You're actually dealing with the code in Swift.

298
00:32:59,920 --> 00:33:08,000
- Yeah. Yeah. I don't recall. Now, Danger was, I think, originally at least, like it's JavaScript

299
00:33:08,000 --> 00:33:12,560
based, right? And I think it had Swift extensions where you could write stuff in Swift as well.

300
00:33:12,560 --> 00:33:15,120
- I thought it was Ruby.

301
00:33:15,120 --> 00:33:17,920
- Oh, is it entirely? Oh, Ruby? Yeah, something.

302
00:33:17,920 --> 00:33:23,120
- Although maybe, no, I think actually it is, I think you're right. I think it's JavaScript.

303
00:33:23,120 --> 00:33:27,840
I'm just looking at the website now and the code that I can see looks more JavaScripty than,

304
00:33:27,840 --> 00:33:30,720
well, it is not Ruby. This is JavaScript, yeah.

305
00:33:30,720 --> 00:33:37,120
- So, yeah. I mean, I think there's some overlap, but I think they're also different, you know,

306
00:33:37,120 --> 00:33:42,880
as in Danger supports things that are outside your source code, really. It's more like organizational

307
00:33:42,880 --> 00:33:48,960
linting, you know, like organizational rules that go beyond source code rules. And I think

308
00:33:49,600 --> 00:33:55,440
there might be value in actually having those a little separate because one of them is probably

309
00:33:55,440 --> 00:34:02,320
going to be really tied to your CI system. So, if you're offline, for instance, they might not make

310
00:34:02,320 --> 00:34:07,440
sense because they interact with GitHub, whereas source code rules could run at any time, right?

311
00:34:07,440 --> 00:34:12,960
They could, all they need is the code base itself to establish that the rules are being followed.

312
00:34:12,960 --> 00:34:18,880
And they could be just a component in something that sits on top and makes sure that that box

313
00:34:18,880 --> 00:34:23,840
is ticked in the complete rule set around your pull requests and stuff.

314
00:34:23,840 --> 00:34:31,600
- Yeah. So, well, let's make it a double recommendation then. Harmonize by

315
00:34:31,600 --> 00:34:38,640
Peristreet Software and also Danger, and we'll include links to both of those in the show notes.

316
00:34:38,640 --> 00:34:45,520
- Excellent. All right. My second pick is called Swift Mocking by Grey Campbell.

317
00:34:47,920 --> 00:34:54,560
Now, Swift Mocking is a collection of Swift macros used to generate mock dependencies. And

318
00:34:54,560 --> 00:35:00,320
we've talked about various ways of mocking tests in the past, but I think one of the most common

319
00:35:00,320 --> 00:35:06,080
ways is really to create a protocol for your functionality and then inject a dependency

320
00:35:06,080 --> 00:35:11,600
as a conformer to that protocol. So, you know, you might have networking and then you have a

321
00:35:11,600 --> 00:35:18,240
protocol that defines your networking calls. And typically you'd inject URL session as your

322
00:35:18,240 --> 00:35:24,320
live version of your functionality. And then in your test, you insert, you know,

323
00:35:24,320 --> 00:35:29,600
inject a mock that also conforms to your networking protocol, but implements it very

324
00:35:29,600 --> 00:35:34,720
differently. And typically, you know, without any logic, it just has state and allows you to

325
00:35:35,520 --> 00:35:42,400
control its internal state and also what it returns when, you know, functionality on it is called.

326
00:35:42,400 --> 00:35:51,120
But setting this up can often be quite tedious because you sort of end up having to conform to

327
00:35:51,120 --> 00:35:57,920
a protocol twice, right? For your live version, you know, if it's not like URL session, if it's

328
00:35:57,920 --> 00:36:02,080
one of your dependencies that you're trying to mock, then you have to implement the live service

329
00:36:02,640 --> 00:36:06,800
and then also have to do quite a bit of setup around your mock. You know, you need to

330
00:36:06,800 --> 00:36:12,160
edit for all the functions that you want to stub, and then you probably need to keep some internal

331
00:36:12,160 --> 00:36:16,560
state, what these functions do, you know, store the parameters that they're getting, for instance,

332
00:36:16,560 --> 00:36:22,400
in order to inspect them later on, act on them, that sort of stuff. And that's where this comes

333
00:36:22,400 --> 00:36:30,640
in because it's a macro that you just attach to a protocol, and then it will generate all this

334
00:36:30,640 --> 00:36:37,360
for you. It'll generate the stubs that conform to the protocol and keep the state around and give you

335
00:36:37,360 --> 00:36:44,560
for free hooks into that state and into the calls and the responses so that you can actually set up

336
00:36:44,560 --> 00:36:50,800
your object as you want, right? You might say, well, if you get a network request, always return

337
00:36:50,800 --> 00:36:57,520
a 200, right? Or always return a 404, and then your test can handle what happens in that case.

338
00:36:57,520 --> 00:37:01,520
And you can also inspect when a call comes into your network. For instance, you could inspect,

339
00:37:01,520 --> 00:37:06,880
well, what's the URL this has been called with and what's the payload and ensure that you're

340
00:37:06,880 --> 00:37:12,080
setting up your network calls correctly, for instance. And that's all implementation you

341
00:37:12,080 --> 00:37:18,560
normally have to set up, and this macro will give you that for free and sort of type all this out

342
00:37:18,560 --> 00:37:22,400
for you. And the reason why I think this is an interesting project, and I'm sure it's not the

343
00:37:22,400 --> 00:37:30,240
only one, it's the most recent one that I've seen, is that I recall early on when Swift was newer,

344
00:37:30,240 --> 00:37:36,480
one of the criticisms was it's a static language and it really prevents us from doing things like

345
00:37:36,480 --> 00:37:42,640
this, for instance, like mocking, because typically in other languages, it's deployed

346
00:37:42,640 --> 00:37:47,280
dynamically. So, like, you have an object that you want to mock, and then at runtime, the thing is

347
00:37:47,280 --> 00:37:52,400
inspected and everything is rewritten on the fly. Like, reflection is being used to see, well,

348
00:37:52,400 --> 00:37:57,600
what properties does the thing have? What functions does it have? And then these are sort of, you know,

349
00:37:57,600 --> 00:38:03,760
like in Objective-C terms, swizzled and replaced at runtime. And that Swift can't do because it's

350
00:38:03,760 --> 00:38:09,920
static language. I mean, there's some means of doing stuff like that, but it's sort of hackery

351
00:38:09,920 --> 00:38:15,760
and not well supported. But with macros, that's actually not the case anymore, because effectively

352
00:38:15,760 --> 00:38:21,680
that can be done at compile time, just by a lot of typing and the macro system does all the typing

353
00:38:21,680 --> 00:38:26,320
for you. So, you actually get the best of both worlds, right? It sort of appears to be dynamic

354
00:38:26,320 --> 00:38:32,640
because it knows how all of this needs to be done. It doesn't need to do it at runtime because it can

355
00:38:32,640 --> 00:38:38,640
sort of reflect in advance, if you will, by looking at the type declaration and type it all out for

356
00:38:38,640 --> 00:38:44,080
you, what normally would happen at runtime via discovery. So, we're sort of closing a loop a bit

357
00:38:44,080 --> 00:38:51,120
with a macro system where a lot of the things that early on were missing because Swift wasn't

358
00:38:51,120 --> 00:38:56,960
dynamic enough are sort of now filled in by the macro system, you know, pulling it back, so to

359
00:38:56,960 --> 00:39:03,280
speak. And I think that's a really nice thing to see. We all do know that there are some downsides

360
00:39:03,280 --> 00:39:10,720
to macros still because of the compile time cost you pay, but hopefully with Swift 6.2,

361
00:39:11,520 --> 00:39:18,640
we see some change there and then it's just a win, you know, all around. So, yeah, there you go.

362
00:39:18,640 --> 00:39:23,280
This was also on my, not on my main list, but it was on my extended list,

363
00:39:23,280 --> 00:39:28,160
which I'm glad I didn't pick it because we would have literally clashed with everyone then.

364
00:39:28,160 --> 00:39:34,560
But yeah, I thought this looked really interesting. And like you say, I think the fact that

365
00:39:35,840 --> 00:39:43,360
macros do have that cost to them at the moment, I think we're about to see a lot more use of macros

366
00:39:43,360 --> 00:39:51,280
when that cost goes away. And I really consider the launch of macros to be whenever we don't

367
00:39:51,280 --> 00:40:01,040
have that cost because they do feel really quite heavyweight to kind of, they feel like a heavy

368
00:40:01,040 --> 00:40:08,880
thing to include at the moment. And so I'm very hopeful for what we'll see macros do. I think

369
00:40:08,880 --> 00:40:13,520
we've only, let me put it this way, I think we've only seen the start of what people will use macros

370
00:40:13,520 --> 00:40:19,520
for so far. Yeah, yeah, definitely. I think the other thing to be a bit wary about with macros is

371
00:40:19,520 --> 00:40:27,920
if something goes wrong, it can be difficult to deal with errors in macros. You know, if you have

372
00:40:27,920 --> 00:40:33,360
like, if you have a bug in the macro, or if you're misusing them, it can, because you might have to

373
00:40:33,360 --> 00:40:38,000
look at what the macro actually typed out, you know, like the expansion of the macro. And that

374
00:40:38,000 --> 00:40:42,560
can be, that can be a lot. But you can see. Yeah, you can. I mean, it's nice that you can actually

375
00:40:42,560 --> 00:40:50,000
see it in line. I love that. But the thing is, because a lot of the stuff is, I mean, it is

376
00:40:50,000 --> 00:40:55,520
generated, but it also has to sort of, in order to avoid, you know, like, for example, name clashes,

377
00:40:55,520 --> 00:41:02,720
you often see really strange names, because the designers have to step around your code a bit,

378
00:41:02,720 --> 00:41:06,960
right? If you name certain things, certain ways, they have to make sure that they don't clash. And

379
00:41:06,960 --> 00:41:13,280
then you end up with, like, really weird type names and stuff. So it can look really weird,

380
00:41:13,280 --> 00:41:19,840
if you look at macro code, almost as if you looked at, you know, like, it's not assembly, but

381
00:41:19,840 --> 00:41:25,280
it is certainly not your typical Swift code that you look at. But I've had cases where

382
00:41:26,080 --> 00:41:32,560
it really helped. Like I was using a package in early on where it was being developed. And I was

383
00:41:32,560 --> 00:41:39,120
using, like, I was example was type throws, and the macro package wasn't really written for type

384
00:41:39,120 --> 00:41:43,760
throws yet. And I got compiler errors that I didn't understand. But then the expansion actually

385
00:41:43,760 --> 00:41:50,560
helped explain why, why it didn't work and allowed me to find workarounds on my end or talk to the,

386
00:41:50,560 --> 00:41:56,320
to the authors to find other workarounds. And that's, that's possible. But it's, it's also not,

387
00:41:56,320 --> 00:42:02,160
it's not quite the same as drilling into source code that is that is written for a

388
00:42:02,160 --> 00:42:09,360
programmer to read rather, because Swift's macros are written for the compiler to read and compile,

389
00:42:09,360 --> 00:42:15,200
really, they're not, they're not really written for you to see or understand at a glance. And

390
00:42:15,200 --> 00:42:19,760
that's something to bear in mind. And I don't think there's really a solution for that. That's

391
00:42:19,760 --> 00:42:26,240
just the nature of the beast. Just as, as, you know, assembly is, that's just the nature of the

392
00:42:26,240 --> 00:42:30,320
beast, right? That's what it compiles down to. This is sort of an intermediate step that is sort

393
00:42:30,320 --> 00:42:36,160
of a bit more understandable, but it's it is lower level. And that's something to bear in mind as

394
00:42:36,160 --> 00:42:49,360
well. Fantastic. I think I have one more package to talk about this week, which is Vault Courier by

395
00:42:49,360 --> 00:42:56,960
Javier Cuesta. And you may have remember us talking about Javier before because Javier is

396
00:42:56,960 --> 00:43:07,040
a previous participant in the Swift mentorship program, and did some fantastic work with adding

397
00:43:07,040 --> 00:43:14,320
author support on Swift package index. So he added in every package page, you'll see the

398
00:43:15,360 --> 00:43:21,200
author information, which is extracted either from the git history, or you can override it in your

399
00:43:21,200 --> 00:43:29,760
spi.yaml file. And Javier was responsible for implementing that feature, which is great,

400
00:43:29,760 --> 00:43:37,360
fantastic step forward for the project. But also now he has released this package, which if you

401
00:43:37,360 --> 00:43:46,720
are a user of either HashiCorp Vault or OpenBAU, which are both tools for security, securely

402
00:43:46,720 --> 00:43:54,880
storing secrets, API tokens, database credentials, certificates, tends to be as your project gets

403
00:43:54,880 --> 00:44:03,520
gets to be interacted with by more than just a few people, the secret storage and that kind

404
00:44:03,520 --> 00:44:09,600
of storage becomes a problem. And there are several, both open source and commercial

405
00:44:09,600 --> 00:44:19,440
solutions to that problem, of which HashiCorp Vault and OpenBAU is two of them. And so Vault

406
00:44:19,440 --> 00:44:28,400
Courier is a client for server side Swift, or most likely server side Swift that can access both of

407
00:44:28,400 --> 00:44:33,760
those services. And I know, because he and I have been chatting a little bit about this as he's

408
00:44:33,760 --> 00:44:40,880
developed it. I know, this is a kind of passion project for him. And he's also put an enormous

409
00:44:40,880 --> 00:44:47,680
amount of work into this. So I thought it was worth highlighting it here. If you are in that

410
00:44:47,680 --> 00:44:52,720
situation, where we're actually not in that situation yet with Swift package index, because

411
00:44:53,840 --> 00:45:01,120
we tend, we're still using kind of environment variables, that kind of stuff for our secrets.

412
00:45:01,120 --> 00:45:11,840
But I think it's where projects kind of outgrow that mechanism, then this is the kind of solution

413
00:45:11,840 --> 00:45:16,720
that you might be looking at. - Yeah, that sounds really interesting. Yeah. Nice.

414
00:45:16,720 --> 00:45:21,600
- So we'll finish off with the server side Swift package, but I think that will be it for

415
00:45:22,240 --> 00:45:30,800
this episode of the podcast. And we'll call it a day there. We will be back in three weeks time,

416
00:45:30,800 --> 00:45:34,960
but in three weeks time, I think, let me just check the dates. I have a feeling that in three

417
00:45:34,960 --> 00:45:44,480
weeks time, it is WWDC week. No, it's the week before WWDC. So we'll have one more episode,

418
00:45:44,480 --> 00:45:49,600
and then the week after that will be the conference. - Fantastic.

419
00:45:49,600 --> 00:45:55,280
- So we'll see you then. All right. - All right. See you then. Bye-bye.

420
00:45:55,280 --> 00:45:56,720
- Thank you. Bye-bye.