1
00:00:00,001 --> 00:00:08,320
A big piece of news recently was that the Swift language account, social media account,

2
00:00:08,320 --> 00:00:14,640
is now on Mastodon and BlueSky. There was an announcement on the Swift forums. This is a

3
00:00:14,640 --> 00:00:19,360
follow-up to a discussion that was also on the Swift forums where someone asked what the state

4
00:00:19,360 --> 00:00:25,440
is of moving and apparently took quite a bit of effort to get this going. And it's great to see

5
00:00:25,440 --> 00:00:32,160
that this is finally happening because I think I know there have been a lot of people, myself

6
00:00:32,160 --> 00:00:37,040
included, who moved off of Twitter quite a while ago and were sort of cut off from any official

7
00:00:37,040 --> 00:00:43,920
Swift language announcements. I mean, it wasn't hard to see or hear about stuff that was happening,

8
00:00:43,920 --> 00:00:49,440
but it is kind of nice to have the official accounts in the places where people are, right?

9
00:00:50,080 --> 00:00:57,120
And that has changed very significantly. To my knowledge, that doesn't mean that the Twitter

10
00:00:57,120 --> 00:01:05,920
account has been abandoned. This is something I personally wish would happen too. Twitter has been

11
00:01:05,920 --> 00:01:12,640
a platform that runs counter to the values Apple usually promote in and around the company. And

12
00:01:12,640 --> 00:01:17,680
ever since the Musk takeover, I think it's very clear that this is going in a very different

13
00:01:17,680 --> 00:01:23,040
direction. And I think it dilutes their message quite significantly. I don't think you can have

14
00:01:23,040 --> 00:01:31,760
it both ways here. Promote these values and then be on Twitter. That's my personal opinion. I just

15
00:01:31,760 --> 00:01:37,040
feel like I'm wanting to say that actually. And this is also something that Matt Massicotte

16
00:01:37,040 --> 00:01:43,840
addressed in his blog post, Leverage, that he posted a few weeks ago. And I think you also

17
00:01:43,840 --> 00:01:48,960
mentioned in Iowa's Step Weekly at the time. I did. Yeah. Yeah. And he wrote that in response

18
00:01:48,960 --> 00:01:52,960
specifically to Apple recommencing their advertising on Twitter, which I think goes

19
00:01:52,960 --> 00:02:01,040
even beyond just being present on the platform. It's actually giving money to the platform. I

20
00:02:01,040 --> 00:02:07,120
think that's even a step beyond that. And I feel it's important that we make our voices heard here.

21
00:02:07,120 --> 00:02:13,120
It's something I want to do on this occasion. I don't think it's a good look for Apple to be

22
00:02:13,120 --> 00:02:19,600
present on Twitter in general, but particularly to give the platform money, as I said. And I

23
00:02:19,600 --> 00:02:24,160
recall a time when Parler, for instance, was removed from the App Store because it violated

24
00:02:24,160 --> 00:02:31,040
the policy. And I don't think Twitter is significantly different of a platform these

25
00:02:31,040 --> 00:02:36,000
days. If anything, it's worse if you look at what's being posted there and by whom in particular.

26
00:02:36,000 --> 00:02:43,040
I know these things aren't easy. There's probably a lot of pressure on the company to keep doing

27
00:02:43,040 --> 00:02:48,480
certain things. But leadership is doing the hard bits, right? If stuff was easy,

28
00:02:48,480 --> 00:02:54,880
there was no need for leadership. Personally, and I've also expressed this on Masternod,

29
00:02:54,880 --> 00:03:00,240
I quite struggle with the fact that Apple is sponsoring Swift Package Index, which allows

30
00:03:00,240 --> 00:03:06,560
me and us to work on this project that I love. But that same Apple is giving money to Musk. And

31
00:03:06,560 --> 00:03:13,680
I think that's a bit of a bitter pill to swallow. I can rationalize this to a degree because I know

32
00:03:13,680 --> 00:03:20,720
Apple is not a monolith. We're dealing with various different parts of Apple. And I suspect

33
00:03:20,720 --> 00:03:26,720
there's lots of people, in fact, I know there are people at Apple who have different opinions

34
00:03:26,720 --> 00:03:32,720
because I see them post them. And it's a huge company and there's always going to be different

35
00:03:32,720 --> 00:03:39,200
ideas around how to do things. And as I said, I know there are certain pressures, but I think

36
00:03:39,200 --> 00:03:47,440
it's important to not lose sight of what you actually want to be seen as standing up for.

37
00:03:47,440 --> 00:03:54,320
And I think the association here is bad. And I wish all of Apple took a stronger stand in this

38
00:03:54,320 --> 00:04:05,520
regard. So yeah, that's my little soapbox moment. - I mean, I agree on the Twitter thing, of course.

39
00:04:05,520 --> 00:04:10,160
I wrote some stuff in iOS Dev Weekly, as you mentioned. I don't really have anything to add

40
00:04:10,160 --> 00:04:19,120
to what you just said then. Well, what I will say is that it is great to see Blue Sky and

41
00:04:19,760 --> 00:04:27,120
Macedon support for the Swiftlang account, to see them active there. And actually, the other

42
00:04:27,120 --> 00:04:37,200
thing that's worth mentioning is that before the adoption of the two new social networks,

43
00:04:37,200 --> 00:04:46,320
I know that the Swift team have been doing more promotion on social media. So they've actually

44
00:04:46,320 --> 00:04:53,840
been using some of the package recommendations through the package page on the Swift website

45
00:04:53,840 --> 00:05:00,400
to promote some of those packages through social media. And of course, now those are going to be

46
00:05:00,400 --> 00:05:07,520
on all the platforms as well as just Twitter. So it is good to see that not only there is an

47
00:05:07,520 --> 00:05:13,600
expansion of the platforms, but also that there's an expansion of the usage of those accounts as

48
00:05:13,600 --> 00:05:18,720
well. - Yeah. And just to reiterate, I think it's great to see that adoption of Macedon and Blue

49
00:05:18,720 --> 00:05:24,080
Sky and my little rant wasn't intended to sort of dilute that message. I think that's great that

50
00:05:24,080 --> 00:05:29,440
it's happening. And I guess small steps, maybe there's a discussion to be had about taking it

51
00:05:29,440 --> 00:05:35,760
further, but this is great to see. And I also have seen that the Swiftlang account has picked up some

52
00:05:35,760 --> 00:05:40,640
of the links. I don't know about the change because I haven't seen what happened or is happening on

53
00:05:40,640 --> 00:05:47,120
Twitter, but it's just great in general to see them show up in these places now. - Well, that's

54
00:05:47,120 --> 00:05:52,480
the irony of it. I heard about this happening. I didn't see it happening because I also don't use

55
00:05:52,480 --> 00:05:58,960
Twitter anymore. So I didn't see it through seeing the posts. I saw it through people telling me

56
00:05:58,960 --> 00:06:05,600
that there were posts. - Right. Okay. - Which is a far more pleasant way to use Twitter in my

57
00:06:05,600 --> 00:06:16,880
experience. - Twitter by osmosis. - Exactly. Yeah. By proxy. Yep. All right. Let's move on to

58
00:06:16,880 --> 00:06:25,120
something else. One thing that I wanted to talk about this week was we've had a fairly long

59
00:06:25,120 --> 00:06:36,080
standing issue with our ready for Swift 6 page that we did last year, which is the collection

60
00:06:36,080 --> 00:06:42,720
and reporting of the number of data race safety issues that the Swift compiler is reporting

61
00:06:42,720 --> 00:06:49,040
if it were in Swift, or that it would report if it were in Swift 6 language mode. And we display

62
00:06:49,040 --> 00:06:56,400
that on every package page as an indicator of whether a package has data race safety errors.

63
00:06:56,400 --> 00:07:05,120
And we also have this, we still have the ready for Swift 6 page on the site, which shows those

64
00:07:05,120 --> 00:07:12,400
numbers over time, basically, as the Xcode releases happened over last summer. We have the kind of

65
00:07:12,400 --> 00:07:18,560
historic view of the number of data race safety errors across the entire package ecosystem.

66
00:07:18,960 --> 00:07:24,160
But of course, at this point now, the information on the package page is the most important thing.

67
00:07:24,160 --> 00:07:34,560
And what we saw as we kind of looked into this in some detail, is that there are certain situations

68
00:07:34,560 --> 00:07:43,440
where package authors are dealing with and potentially suppressing in completely legitimate

69
00:07:43,440 --> 00:07:50,240
ways, data race safety errors. And the numbers that were coming out of the stats system in the

70
00:07:50,240 --> 00:07:56,960
Swift compiler were not representing those suppressions correctly. I think that's pretty

71
00:07:56,960 --> 00:08:02,640
much a reasonable summary of it. Yeah, maybe suppression is like, you mean like fixing or

72
00:08:02,640 --> 00:08:08,000
addressing? Yeah, suppression is the wrong word. Yeah, suppression is the wrong word. I knew it,

73
00:08:08,000 --> 00:08:11,920
as I was saying, I was saying the wrong word. I think specifically, like if you add

74
00:08:11,920 --> 00:08:21,200
pre-concurrency imports, where you effectively indicate, well, this library isn't Swift 6 ready,

75
00:08:21,200 --> 00:08:28,720
but I want to use it, I have to use it. And I know it's a legitimate use of that. And I think

76
00:08:28,720 --> 00:08:34,560
the false positives there were that these certain errors were still being counted as errors,

77
00:08:34,560 --> 00:08:40,480
even though they weren't actually showing up as errors when you run the build with Xcode and Swift

78
00:08:40,480 --> 00:08:49,280
build. That's it. That's exactly it. So anyway, the good news is that we reported the error to the

79
00:08:49,280 --> 00:09:00,800
Swift GitHub repository. And the great news is that that error has now been fixed. It's not entirely

80
00:09:00,800 --> 00:09:08,480
clear whether that merge, so the fix has been merged, but whether it has been merged into 6.1,

81
00:09:08,480 --> 00:09:14,960
which is now in beta, or whether we may have to wait for 6.2 for that to get through into an actual

82
00:09:14,960 --> 00:09:21,920
tool chain that ships with Xcode and, you know, is in the Linux release as well. But the good news

83
00:09:21,920 --> 00:09:28,320
is it's fixed. So we should, there is light at the end of the tunnel for being able to report

84
00:09:28,320 --> 00:09:36,000
truly accurate beta race safety numbers, as you would see if you open the project in Xcode.

85
00:09:36,000 --> 00:09:42,160
Yeah, yeah, I've made a note. So by next time, we'll know. And depending on the outcome,

86
00:09:42,160 --> 00:09:50,080
well, maybe in general, we will run a new run with 6.1 is out, we sort of stopped doing the

87
00:09:50,080 --> 00:09:56,240
every two week runs, because with the numbers, sort of uncertain, it didn't really make that

88
00:09:56,240 --> 00:10:03,280
much sense to stress the system every two weeks with something where we knew a lot of packages,

89
00:10:03,280 --> 00:10:10,480
where we're seeing issues. And yeah, it felt like, you know, not worth the effort,

90
00:10:10,480 --> 00:10:16,240
without that error actually being fixed. So we know we get good numbers.

91
00:10:16,240 --> 00:10:22,320
But it's going to be really great to see those numbers finally be something that people can rely

92
00:10:22,320 --> 00:10:32,160
on. Where at the moment, I think we actually have a slightly softened wording on, I'm trying to find

93
00:10:32,160 --> 00:10:38,320
a package with data race errors, and I can't find one. Isn't that great? I clicked on four packages

94
00:10:38,320 --> 00:10:42,720
there and not a single one had data race safety errors. In fact, I'm clicking on more and none

95
00:10:42,720 --> 00:10:46,800
of them have data race safety errors. That's just amazing. Let's keep rolling while you find one.

96
00:10:46,800 --> 00:10:50,480
You should play some suspense music when you do the editing.

97
00:10:50,480 --> 00:10:58,000
Exactly. This is remarkable. I'm still clicking and I can't find any. Okay, but I'm sure we

98
00:10:58,000 --> 00:11:03,680
softened the wording slightly to say there may be data race safety errors or something like that.

99
00:11:03,680 --> 00:11:08,640
I think GRDB is one because that's actually a false positive. So I think it should list an error.

100
00:11:08,640 --> 00:11:14,080
If you want to check that one. Here we go. That's it. I'm loading it up right now.

101
00:11:14,080 --> 00:11:20,800
Yeah, so it actually, maybe we didn't soften it because it does say has data race safety errors.

102
00:11:21,680 --> 00:11:30,000
And that will be fixed. So it's great news. Excellent. All right. The other bit of news

103
00:11:30,000 --> 00:11:36,400
regarding the Swift package index was that we have just finished the transition of moving all

104
00:11:36,400 --> 00:11:42,240
of our tests from XCTest to Swift testing. So Swift testing is the new testing framework that

105
00:11:42,240 --> 00:11:52,720
was announced at last WWDC and shipped with Swift 6. So that was the first version that had it.

106
00:11:52,720 --> 00:12:01,360
Swift 6.1 has an additional feature in Swift testing, which we will want to be using. But

107
00:12:01,360 --> 00:12:06,000
the initial transition is actually just needs Swift 6. So that was sort of one of the things

108
00:12:06,000 --> 00:12:12,000
that we were waiting for. But also, you know, the obvious first question is, well, why would you even

109
00:12:12,000 --> 00:12:18,480
want to do that? Because our tests were working. We have a lot of them. So why actually try and do

110
00:12:18,480 --> 00:12:24,720
that? Ultimately, the reason is we want to try and run our tests in parallel. We have a lot of them.

111
00:12:24,720 --> 00:12:30,720
They're using actual live database connections that run in the Docker container. And the idea

112
00:12:30,720 --> 00:12:37,680
is to speed that up. So they are slow because of that. We have around 800 tests. And they take,

113
00:12:37,680 --> 00:12:42,160
I think in CI, they take 10 minutes. It's off the order of minutes.

114
00:12:42,160 --> 00:12:46,160
No, it's like, yeah, 10 to 15 minutes, I would say.

115
00:12:46,160 --> 00:12:50,800
Well, a lot of it is the build. So that's why I hesitate. The whole thing, the whole CI runs 20

116
00:12:50,800 --> 00:12:56,000
minutes. But a lot of that is actually the build. Because in the CI system, that's quite slow. It

117
00:12:56,000 --> 00:13:02,880
might be 10 minutes build, 10 minutes test run. But even locally, where I think the most important

118
00:13:02,880 --> 00:13:09,920
is the full test suite right now on my machine runs in two and a half to three minutes. And that

119
00:13:09,920 --> 00:13:15,200
is quite significant. When you've done something, you know, you kind of want to have a quick check.

120
00:13:15,200 --> 00:13:23,200
That's not a quick check anymore. And the idea here is to just run the tests in parallel and

121
00:13:23,200 --> 00:13:29,600
cut down that time significantly. Now, in principle, that would be possible with XCTest. But

122
00:13:29,600 --> 00:13:36,640
there are a couple of shortcomings with XCTest that make that harder. And I did a little exploration

123
00:13:36,640 --> 00:13:42,240
before I embarked on this whole thing. And I concluded, it's not actually worth the time

124
00:13:42,240 --> 00:13:48,240
trying to fix that in XCTest. It's actually better to just transition and then do it properly in

125
00:13:48,240 --> 00:13:54,080
Swift testing. Because obviously, that's the thing that's going to carry us forward much further than

126
00:13:54,080 --> 00:13:59,600
XCTest ever could. And it also has obviously a lot of other nice things about it, you know, like

127
00:13:59,600 --> 00:14:09,520
better asserts, expect macros, give a nicer printout. And it's faster, actually, the test

128
00:14:09,520 --> 00:14:19,200
discovery is faster. Also, like Linux and macros tests actually run in the same way now. Lots of

129
00:14:19,200 --> 00:14:26,160
little things and bigger things that come together that make this worthwhile. But also, there is one

130
00:14:26,160 --> 00:14:32,640
piece of sort of a tool that really makes that feasible at all. And that is something I mentioned

131
00:14:32,640 --> 00:14:41,920
before on the podcast, I think I even had as a package pick. And that is Swift Testing Evolutionary.

132
00:14:41,920 --> 00:14:53,120
That's a package that was driving this transition. And I'll get into it a bit more. But I just want

133
00:14:53,120 --> 00:14:59,440
to describe the sort of where we started off. So we had our test suite is, as I said, quite

134
00:14:59,440 --> 00:15:07,360
significant, we have 105 tests, like test classes, which turn into test suites and Swift testing,

135
00:15:07,360 --> 00:15:19,440
with overall 798 tests. So that's the individual test methods on XCTest, which get turned into

136
00:15:19,440 --> 00:15:31,040
these at test attributed functions. And inside of those we have 2300 asserts. That's what gets

137
00:15:31,040 --> 00:15:36,640
turned into these expect and require macros after conversion. And you can imagine, I mean, you can

138
00:15:36,640 --> 00:15:44,080
you can potentially manually transform 105 test classes into suites, that's sort of not something

139
00:15:44,080 --> 00:15:50,320
crazy. You could conceivably convert the tests, you know, because that's maybe doable with

140
00:15:50,320 --> 00:15:58,320
replace, you know, some some replace magic. But all the asserts is just that would be madness.

141
00:15:58,320 --> 00:16:02,800
And this is where this tool Swift Testing Revolutionary comes in, because it does that

142
00:16:02,800 --> 00:16:10,960
for you, it actually uses Swift syntax to look at the test structure and rewrites all the code,

143
00:16:10,960 --> 00:16:19,120
it rewrites the test suites, the test functions into the attribute test functions, and it rewrites

144
00:16:19,120 --> 00:16:23,360
the asserts. And that's a critical piece. And it does a really, really good job. There are a couple

145
00:16:23,360 --> 00:16:31,920
of cases where it doesn't quite work. It's mainly around where you have where you try to test

146
00:16:31,920 --> 00:16:39,280
exceptions or not. Yeah, exceptions and have throwables that you want to assert. So there's

147
00:16:39,280 --> 00:16:44,880
a bit of syntax weirdness that you have to deal with manually. But the vast majority of these,

148
00:16:44,880 --> 00:16:52,400
I'd say like 95% of these assert conversions, it does automatically. And that is just huge,

149
00:16:52,400 --> 00:16:59,440
because that really makes that feasible at all. Because otherwise, if this tool didn't exist,

150
00:16:59,440 --> 00:17:04,240
I don't think I would have done that transition, certainly not within the time it took in the end.

151
00:17:04,240 --> 00:17:10,400
So I started this in on February 5, and I finished on March 5. And this was not a full time project.

152
00:17:10,400 --> 00:17:16,640
This was, you know, as I went along, I did, every day, I did a couple of test cases that I converted

153
00:17:16,640 --> 00:17:23,680
and tweaked. Obviously, I picked a difficult one up front to see, you know, which bits are

154
00:17:23,680 --> 00:17:28,400
potentially hard to convert. And there was a bit of upfront work I had to invest because

155
00:17:29,920 --> 00:17:35,120
there are a couple of structural differences between XC testing and Swift testing. They're

156
00:17:35,120 --> 00:17:47,520
mainly around sort of I pattern, which is resource acquisition is initialization. By that I mean,

157
00:17:47,520 --> 00:17:52,640
when you use a database connection, for instance, in a test, you typically set that up in a test

158
00:17:52,640 --> 00:17:58,800
setup function. And then you tear down in a test tear down, you know, because we have a Docker

159
00:17:58,800 --> 00:18:04,720
container that we run against, and we don't want to have tests, cross talk where one test would

160
00:18:04,720 --> 00:18:09,280
leave around stuff that the next test then sees and, you know, it would affect the results.

161
00:18:09,280 --> 00:18:15,280
So what we do is we do a schema setup, and then a schema wipe at the end of the test or at the

162
00:18:15,280 --> 00:18:20,960
start of the next test. And that is something that works a bit differently between the two

163
00:18:20,960 --> 00:18:26,400
mechanisms. And that was a piece that really required a bit of redoing. But once I'd done

164
00:18:26,400 --> 00:18:32,400
that, it was really quite easy and mechanical to convert the tests over. So if you're planning to

165
00:18:32,400 --> 00:18:38,320
do this yourself, I'd really recommend pick a test that you know is sort of complicated deals with

166
00:18:38,320 --> 00:18:43,760
some external dependencies, stuff like that maybe is is testing something very complicated,

167
00:18:43,760 --> 00:18:50,560
convert that. And when when that's working, when you know it convert work on that one, then do the

168
00:18:50,560 --> 00:18:56,960
rest because after that, it'll be really, really easy and quite mechanically especially if you use

169
00:18:56,960 --> 00:19:02,720
Swift testing revolutionary to do the the automated bits for you.

170
00:19:02,720 --> 00:19:12,080
Yeah, that's great. I mean, I, I did look at some of the the the results of the conversion. And I

171
00:19:12,080 --> 00:19:17,200
think it was a curious choice to just replace every assertion with expect true to equals true.

172
00:19:18,000 --> 00:19:21,280
The good news is the test path pass really fast now.

173
00:19:21,280 --> 00:19:24,560
Yeah. Yeah. And not only that, it also gives you more.

174
00:19:24,560 --> 00:19:31,440
I think you missed my joke. Every expectation is replaced with true equals true.

175
00:19:31,440 --> 00:19:38,000
But everything is super fast.

176
00:19:38,000 --> 00:19:40,560
I end up with Sorry, I missed this joke. It was

177
00:19:42,400 --> 00:19:49,120
well, you can you can add a laugh track. I was so focused on the next thing I was gonna say.

178
00:19:49,120 --> 00:19:59,440
Apologies. The other bit that's really nice about a it makes it really easy to to actually write

179
00:19:59,440 --> 00:20:04,240
expectations because it's you just need to expect and then you write it as you normally would you

180
00:20:04,240 --> 00:20:10,480
don't have to think about well, is it? Yeah, like exit he assert equals is it equals accuracy? Well,

181
00:20:10,480 --> 00:20:15,360
actually, is actually bad example, because that's a bit of a gap in in XC, in Swift testing right now.

182
00:20:15,360 --> 00:20:21,920
But what it does is, for many types, it will actually give you really detailed printout if

183
00:20:21,920 --> 00:20:27,520
something is not equal. And that's that's a problem often when you have complex types where you,

184
00:20:27,520 --> 00:20:36,720
they might be equatable. And you the exit he assert equals macro works, the old one, it will show you

185
00:20:36,720 --> 00:20:43,040
there's a you know, it fails properly. But then the output is, is effectively, it doesn't tell

186
00:20:43,040 --> 00:20:49,760
you anything because you just effectively just see what this fails and the the printout is is useless.

187
00:20:49,760 --> 00:20:55,840
And this is where expect macros are, are better because it can drill into a lot of stuff like

188
00:20:55,840 --> 00:21:01,040
arrays and dictionaries and actually pull out the details and give you more information about the

189
00:21:01,040 --> 00:21:06,560
text failure without you actually having to actively instrument that in more detail yourself.

190
00:21:06,560 --> 00:21:14,000
Right. So yeah, it's that's, it's, it's great. I'm, I'm really looking forward now to tackle

191
00:21:14,000 --> 00:21:20,080
the the actual objective in making our tests, which is the parallel parallel. Yeah. And I've

192
00:21:20,080 --> 00:21:27,200
hit a couple of additional problems now as you do. But I think we can at least move some of them

193
00:21:27,200 --> 00:21:33,920
to run in parallel fairly soon. There's a bit of legwork still to do, but I'm quite hopeful that

194
00:21:33,920 --> 00:21:40,080
this will work out. It has worked in principle for one test, the problem is a bit to to do this

195
00:21:40,080 --> 00:21:45,840
for the whole test suite when you run parts of it in parallel and parts of it really need to

196
00:21:45,840 --> 00:21:51,760
still run sequentially, I'll have to figure out if how to best address that. But I'm hopeful that

197
00:21:51,760 --> 00:21:59,760
this, this will work and then then speed things up. Yeah, that's great. Great to see. And I'm happy to

198
00:21:59,760 --> 00:22:09,040
happy to see that Swift testing has been such a positive enhancement. I don't think there's any

199
00:22:09,040 --> 00:22:14,080
kind of steps backwards with Swift testing. I think it's looking great. Yeah. Yeah. And if you

200
00:22:14,080 --> 00:22:20,560
do the transition and you have any questions, there's a great Slack channel on the swift.org,

201
00:22:20,560 --> 00:22:27,840
the official Slack Swift dash testing, where Jonathan Greenspan, for instance, is very responsive

202
00:22:27,840 --> 00:22:34,560
to questions. And, you know, just pop in that channel if you encounter any any difficulties.

203
00:22:34,560 --> 00:22:40,880
There are a couple of rough edges still that are being ironed out right now. But overall, it's

204
00:22:40,880 --> 00:22:46,640
really pleasant to work with. And if you run into any issues, people there are really super helpful

205
00:22:46,640 --> 00:22:53,200
and will get you will get you going. All right. I think there's just one very short other piece

206
00:22:53,200 --> 00:22:59,440
of news, right? There is indeed. Yes. And that was a blog post that was announced on the Swift

207
00:22:59,440 --> 00:23:06,080
forums, I think just earlier this week or in the last week. Swift on Raspberry Pi building

208
00:23:06,080 --> 00:23:15,440
natively and cross compiling by Nathan Volnick, assisted by Jesse Zamora. And that's sort of our

209
00:23:16,240 --> 00:23:22,880
our ongoing topic of Swift in unusual places. Maybe not that unusual. I think Raspberry Pi

210
00:23:22,880 --> 00:23:29,440
has sort of been a supported platform for quite a while. But this is really great post that gets you

211
00:23:29,440 --> 00:23:36,160
started. You know, like if you have a Raspberry Pi and nothing else, you it'll it'll walk you

212
00:23:36,160 --> 00:23:42,160
through how to set the thing up even not just about Swift, but just Raspberry Pi in general,

213
00:23:42,160 --> 00:23:48,640
what images to flash onto the thing and then how to get Swift onto it. Get a program running,

214
00:23:48,640 --> 00:23:55,760
compile stuff there directly, but also do the cross compilation, which is super useful. And

215
00:23:55,760 --> 00:24:01,760
because the Raspberry Pi can be slow to compile Swift stuff. I mean, obviously, it's it's not a

216
00:24:01,760 --> 00:24:10,400
machine comparable to a Mac compiling stuff. And that's, that's great. Now, I think it was Swift 6

217
00:24:10,400 --> 00:24:17,520
that introduced proper cross compilation was possible before, but now it's a properly supported

218
00:24:17,520 --> 00:24:23,120
setup, which means on your Mac, you can you download and prepare a specific tool chain for

219
00:24:23,120 --> 00:24:29,200
cross compilation, and then you pass a flag to the compilation command and you get a binary that is

220
00:24:29,200 --> 00:24:37,440
that you just SSH or SCP over to the Raspberry Pi and run there. And that's that's that. So you

221
00:24:37,440 --> 00:24:42,880
can cut down on compile times quite a lot, especially if you have a beefy Mac, that should

222
00:24:42,880 --> 00:24:49,680
help a lot to get you going on your Raspberry Pi projects. So yeah, give that give that blog post

223
00:24:49,680 --> 00:24:56,400
a look if you're into that sort of thing. That's great. Okay, should we do some package

224
00:24:56,400 --> 00:25:03,200
recommendations? Let's do it. Yeah, I shall kick us off this week. And I'm going to start with

225
00:25:04,480 --> 00:25:09,920
a double a double recommendation. They're actually quite different packages, but they're both

226
00:25:09,920 --> 00:25:20,240
brand new and both by the same author. So the author is Robb Böhnke. I'm sorry for butchering

227
00:25:20,240 --> 00:25:25,520
that pronunciation. I think I might help you here because I think I think I was gonna ask

228
00:25:25,520 --> 00:25:34,800
for your assistance because you're German. Okay, sorry, Rob. They're from Robb Böhnke.

229
00:25:34,800 --> 00:25:46,480
And the first one is called AtRandom. And it's a property wrapper that you can use specifically,

230
00:25:46,480 --> 00:25:49,760
I'm sure you can use it for other things. But specifically, it's designed for use within

231
00:25:50,480 --> 00:25:59,280
animation code in SwiftUI. So let's say you wanted to grab a random number to start or affect

232
00:25:59,280 --> 00:26:03,840
some animation by a certain random number. So it's not exactly the same every single time.

233
00:26:03,840 --> 00:26:10,240
You might choose to store that in a state variable because you might want the same random number

234
00:26:10,240 --> 00:26:17,200
every time. But instead, you could use this random property wrapper, and it will create a

235
00:26:17,760 --> 00:26:23,200
persistent random number. So it will be the same random number every time you come into your

236
00:26:23,200 --> 00:26:30,320
into the function. But it will be random on that initial set, I guess it's the property

237
00:26:30,320 --> 00:26:39,360
wrapper version of a C static. So that's really not a not again, not something you're going to

238
00:26:39,360 --> 00:26:46,320
use every day. But I did like the idea of that. And the more you work on SwiftUI code, the more

239
00:26:47,600 --> 00:26:51,840
the state variables can kind of explode, especially with things that are not necessarily

240
00:26:51,840 --> 00:26:58,640
really important to store as state variables like this. So I like that. And the second package from

241
00:26:58,640 --> 00:27:06,320
the same person is called visualized touches. And I've seen a couple of these over the years.

242
00:27:06,320 --> 00:27:10,880
But I really like this one. And it's also compatible with SwiftUI, which is great to see.

243
00:27:11,840 --> 00:27:19,600
So when you're recording a demo of your application, or a tutorial for your application,

244
00:27:19,600 --> 00:27:24,160
or something like that documentation, or whatever it is that you need a screen recording for,

245
00:27:24,160 --> 00:27:33,600
you can, it's useful to be able to show where your fingers are touching on the screen. And Rob

246
00:27:33,600 --> 00:27:41,600
has developed a view modifier for SwiftUI, that you can just add visualize touches on the end of

247
00:27:41,600 --> 00:27:51,120
any SwiftUI view. And it will represent wherever you're touching on your device with two very

248
00:27:51,120 --> 00:27:58,480
beautifully drawn kind of circles to show each fingers kind of placement on that view. Not

249
00:27:58,480 --> 00:28:02,800
something you'd ever want to ship. Because you wouldn't want this happening when people were

250
00:28:02,800 --> 00:28:08,320
actually using your application. But really great for preparing demos and tutorials, like I said.

251
00:28:09,040 --> 00:28:15,920
Yeah, that's such a great thing to have. I always love it when that's actually available.

252
00:28:15,920 --> 00:28:23,200
Sometimes I see people posting screen recordings of their iOS devices. And I really struggle to

253
00:28:23,200 --> 00:28:28,560
see what's actually going on, because I really miss that information. You know, there's no mouse

254
00:28:28,560 --> 00:28:34,240
cursor or anything to guide your eye, to guide you where to look. And I feel like often stuff is

255
00:28:34,240 --> 00:28:39,680
happening and I have no idea what's going on. So I really love that sort of that extension and

256
00:28:39,680 --> 00:28:46,240
videos that actually have that as a tool to guide you. Great packages.

257
00:28:46,240 --> 00:28:55,120
Yeah. And it's, they're just, the touches that get visualized, it seems strange to call them

258
00:28:55,120 --> 00:28:58,720
beautiful because it's just a couple of circles, but they're actually really, they're really nicely,

259
00:28:58,720 --> 00:29:05,520
they're really nicely done. So that's Visualize Touches and AtRandom by Robb Böhnke.

260
00:29:05,520 --> 00:29:13,040
Great. My first pick is a package by, well, who other than pointfree co,

261
00:29:13,040 --> 00:29:20,400
repeat offenders. They keep publishing great packages. I think you also had this

262
00:29:20,960 --> 00:29:25,040
on our Dev Weekly, apologies for mentioning it again. It's SharingGRDB

263
00:29:25,040 --> 00:29:32,320
and this is sort of a double mention also because a while ago,

264
00:29:32,320 --> 00:29:39,280
pointfree co released their package, Swift Sharing, which is perhaps best described as

265
00:29:39,280 --> 00:29:44,160
an observable style macro that allows for a configurable backing store.

266
00:29:45,520 --> 00:29:51,440
What that means is that you can annotate a property in your typically Swift UI project,

267
00:29:51,440 --> 00:29:58,480
let's start there, to be backed by some kind of a store like user defaults, the file system,

268
00:29:58,480 --> 00:30:04,960
whatever, it could even be a server that you connect to. The interesting bit about Swift

269
00:30:04,960 --> 00:30:10,000
Sharing in general is that it's not Swift UI only, and that's how it's different to observable.

270
00:30:12,800 --> 00:30:19,600
You can use this to drive your view models or it's also cross-platform, so you can use it on

271
00:30:19,600 --> 00:30:27,680
Linux for stuff there, for instance. And Sharing GRDB is an extension on top of Swift Sharing,

272
00:30:27,680 --> 00:30:36,720
and it gives you a SQLite-backed store powered by GRDB. And that's a library we talked about

273
00:30:36,720 --> 00:30:42,800
in episode 43. And it's probably the most prominent SQLite library in the Swift ecosystem,

274
00:30:42,800 --> 00:30:50,480
I'd say. So this sort of marries the two packages and gives you the power of Swift Sharing backed by

275
00:30:50,480 --> 00:30:58,560
GRDB as the persistence layer. And all that GRDB gives you on top of this, obviously, available.

276
00:30:58,560 --> 00:31:02,720
And SQLite in general is just a very powerful exchange format too,

277
00:31:04,720 --> 00:31:08,960
meaning you could use this, for instance, also as a file format to ship stuff around.

278
00:31:08,960 --> 00:31:16,240
It's very compelling for that. It's very easy to use and certainly more performant and more

279
00:31:16,240 --> 00:31:20,960
structured than a JSON file or multiple files that you might be moving around here, because

280
00:31:20,960 --> 00:31:28,880
you can use SQLite to then run queries and stuff. You can even run subscriptions on changes. You get

281
00:31:28,880 --> 00:31:33,840
notified if stuff changes in the database and then get notified. And Sharing has a mechanism for that

282
00:31:33,840 --> 00:31:42,240
too. That's what Observable is about, to feed views by updating the database. You can then fan

283
00:31:42,240 --> 00:31:48,400
out and update views automatically. It's quite powerful. Look at it if you are in need for that.

284
00:31:48,400 --> 00:31:58,000
Also worth mentioning is Sharing GRDB back deploys to iOS 13. So that might be a really good

285
00:31:58,000 --> 00:32:04,800
alternative to Swift data, because that is not available to my knowledge that far back. Well,

286
00:32:04,800 --> 00:32:10,480
certainly it isn't, but I don't actually know what the cutoff is for that. So if you have needs for

287
00:32:10,480 --> 00:32:17,040
persistence and Observable style stuff, give this a look. It looks really, really compelling.

288
00:32:17,040 --> 00:32:26,240
That's great. And yes, I did mention that in the newsletter too. It's a great looking package.

289
00:32:26,320 --> 00:32:35,520
My final package for this week is kind of a fun one. I think I am getting a reputation for

290
00:32:35,520 --> 00:32:39,520
maybe making my last package a fun one each week. Maybe that's going to stick.

291
00:32:39,520 --> 00:32:49,840
But it's called AmplifyUILiveness. And it is a wrapper around a Amazon AWS service that can

292
00:32:49,840 --> 00:32:58,720
determine the liveness of a face. Are you looking at a real live human being or are you looking at

293
00:32:58,720 --> 00:33:08,080
a photograph or a simulation of a human being? And it will determine whether, well, it will try

294
00:33:08,080 --> 00:33:13,360
and determine, I don't know how accurate it is, I haven't tried it, but it will attempt to determine

295
00:33:13,360 --> 00:33:20,720
to determine the liveness of the face that you present to it. And so this is actually from,

296
00:33:20,720 --> 00:33:30,240
the package is from AWS Amplify themselves in their organization. And yeah, I just,

297
00:33:30,240 --> 00:33:36,160
I love that idea. I think it's such a, it's a very 2025 problem.

298
00:33:37,280 --> 00:33:44,320
You know what my immediate first thought is, how easy is that going to be to defeat with a photo

299
00:33:44,320 --> 00:33:53,360
and some AI stuff happening on a photo to make it? Well, I think that's the point of it. I think

300
00:33:53,360 --> 00:33:58,800
that's exactly what it is intended to defeat. Oh, really? Okay. Interesting.

301
00:34:00,080 --> 00:34:08,080
And I'm guessing the kind of use for this would be, I know that my bank, every time I need to

302
00:34:08,080 --> 00:34:15,680
log in to my bank's app, if it's somehow found itself, you know, maybe after a major version

303
00:34:15,680 --> 00:34:22,480
upgrade on iOS or something like that, you have to actually record yourself a little selfie video

304
00:34:22,480 --> 00:34:29,440
and send it. And I believe that what they're doing is a human checks it because it's like 15 to 20

305
00:34:29,440 --> 00:34:35,440
minutes before it kind of gets back to you. So I'm guessing that's a human sitting there and

306
00:34:35,440 --> 00:34:45,280
saying, is this the person that is supposed to be? And I'm guessing that this might enable at

307
00:34:45,280 --> 00:34:50,960
least like a pre-check or something like that. I wouldn't want to use something like this for a

308
00:34:50,960 --> 00:34:57,280
positive signal, but it would be great to use this as a negative signal. So this might screen out all

309
00:34:57,280 --> 00:35:03,280
the obviously fake ones or something like that. Yeah. Interesting. Yeah, that's an interesting

310
00:35:03,280 --> 00:35:09,680
package. I hadn't seen that. There we go. I'm going to find the obscure packages every few weeks.

311
00:35:09,680 --> 00:35:16,160
Well, I have no surprise for you because my second pick is also one, apologies again,

312
00:35:16,160 --> 00:35:20,800
I sort of had this on my list as well. And I didn't feel like chucking it because

313
00:35:20,800 --> 00:35:25,360
you mentioned it on our stuff weekly. It's Spices by Simon Støvring.

314
00:35:25,360 --> 00:35:28,560
Do you get all your package recommendations from iOS stuff weekly?

315
00:35:28,560 --> 00:35:36,640
I shall send you messages when I make my picks and make sure that they happen before you publish.

316
00:35:36,640 --> 00:35:41,920
So what was the package? Sorry.

317
00:35:41,920 --> 00:35:51,440
The package was Spices by Simon Støvring. And that's a, as you know, a lovely library to create

318
00:35:51,440 --> 00:36:00,240
debug views and menus from a spec for your app. It's iOS only, I believe. And essentially what

319
00:36:00,240 --> 00:36:07,520
you do, you annotate a Spice store entity with @Spice attributes, like the properties on it.

320
00:36:07,520 --> 00:36:12,640
And then effectively, that's it. That's all you do. Off you go. And it generates a whole view,

321
00:36:12,640 --> 00:36:19,120
a debug view that you can bring up in one way or another. Typically people do it with a shake or

322
00:36:19,120 --> 00:36:27,200
secret gesture or something like a three finger tap, whatever you do. And then you get a really

323
00:36:27,200 --> 00:36:35,680
nice rendering of all the settings that you've added to this Spice store, like Boolean flags or

324
00:36:35,680 --> 00:36:43,200
pop-ups, which API service you might want to connect to, like a QA environment or a staging

325
00:36:43,200 --> 00:36:47,920
environment, that sort of stuff. Stuff that's typically in dev settings for a device.

326
00:36:48,480 --> 00:36:54,000
And have a look at the readme. It has a great little video showing how easy it is to get up

327
00:36:54,000 --> 00:37:01,360
and running with this. And I think it's also a great use of a third party library in this context.

328
00:37:01,360 --> 00:37:07,040
You know, we often talk about when would you use something or how careful do you have to be with

329
00:37:07,040 --> 00:37:14,960
bringing in dependencies? And I think this is a super low risk thing to do because push comes to

330
00:37:14,960 --> 00:37:21,120
shove. Your product release would not depend on this, right? Because it's a pure testing tool.

331
00:37:21,120 --> 00:37:26,560
Obviously it might be an important testing tool, but it's probably not a show-stopping testing

332
00:37:26,560 --> 00:37:33,680
tool if something were to go wrong with this, or for some reason a new Xcode version had troubles

333
00:37:33,680 --> 00:37:37,520
with it and you wouldn't be able to build with it and you had to take it out. That wouldn't be

334
00:37:37,520 --> 00:37:42,720
breaking your bill. So I always like it when dependencies come in that way and give you this

335
00:37:42,720 --> 00:37:49,520
escape hatch of, well, if everything goes pear-shaped, you can at least not use it and

336
00:37:49,520 --> 00:37:54,720
still have a product that you can release. I think in that sense that's a fantastic library to use

337
00:37:54,720 --> 00:38:00,000
and make your dev environment nicer very easily because it's super simple to use.

338
00:38:00,000 --> 00:38:02,960
That sounds great.

339
00:38:02,960 --> 00:38:06,880
Yeah. So there you go. Spices by Simon Støvring.

340
00:38:06,880 --> 00:38:13,520
Fantastic. And we'll call it there, I think. So we will be back in a couple of weeks, well,

341
00:38:13,520 --> 00:38:19,600
a few weeks, with more package recommendations and more news from the world of Swift and Swift

342
00:38:19,600 --> 00:38:23,920
packages. But until then, I think we will see you next time.

343
00:38:23,920 --> 00:38:25,680
See you next time. Bye-bye.

344
00:38:25,680 --> 00:38:26,560
All right. Bye-bye.