1
00:00:00,001 --> 00:00:08,000
So it's warm where you are? It is quite warm, yes. Summer has arrived. Well, it's been here for a while, but it clearly has.

2
00:00:08,000 --> 00:00:19,000
We were just discussing the hardship of having to record a podcast in 33 degree heat with no windows open.

3
00:00:19,000 --> 00:00:27,000
A problem that I do not have. Yeah, I mean, technically I could, so I'm recording this in the winter garden,

4
00:00:27,000 --> 00:00:33,000
and I could, there is AC in here, but it feels like madness cooling this room down for an hour of recording.

5
00:00:33,000 --> 00:00:41,000
I'll just sit through it and I'll try not to make any dripping noises while we record.

6
00:00:41,000 --> 00:00:49,000
Well, it's been very nice here, but actually the last few days have been a little cooler.

7
00:00:49,000 --> 00:00:53,000
It's kind of 15 degrees at the moment, which is very cool for this time of year.

8
00:00:53,000 --> 00:00:57,000
Very pleasant weather to record a podcast in.

9
00:00:57,000 --> 00:01:05,000
Definitely, yeah. More pleasant than here right now. Although I won't trade in general, I'll state that.

10
00:01:05,000 --> 00:01:11,000
Sure, sure. But people are not here for a weather report. They're here for information.

11
00:01:11,000 --> 00:01:18,000
What are people here for? They're not here for the sports, they're not here for the weather. This is confusing.

12
00:01:18,000 --> 00:01:27,000
It confuses me why they're here too. It's possible they're not here. That is a possibility.

13
00:01:27,000 --> 00:01:29,000
There's that, yes.

14
00:01:29,000 --> 00:01:38,000
It's possible we're shouting into the void. But no, they're here for information on package index.

15
00:01:38,000 --> 00:01:48,000
We just finished a new run of the Ready for Swift 6 testing using Xcode 16 Beta 4.

16
00:01:48,000 --> 00:01:54,000
That kicked off just over a week ago and finished a couple of days ago.

17
00:01:54,000 --> 00:02:03,000
I can see the line of packages that are showing zero data race errors is very slowly increasing.

18
00:02:03,000 --> 00:02:19,000
It is and the errors are going down. This is a good trend, but I think we still haven't hit the compiler builds that iron out a fair number of these issues that are known, but just haven't arrived in the public betas yet.

19
00:02:19,000 --> 00:02:29,000
I believe, I hope. We know about a couple of them. There's hope that this moves a bit faster.

20
00:02:29,000 --> 00:02:34,000
We'll have to see how it goes, but at least the trend is right.

21
00:02:34,000 --> 00:02:45,000
I think the main time that we'll see a big increase, if we see a big increase, but I think the main time that we'll see that is actually once Xcode 16 gets released.

22
00:02:45,000 --> 00:02:53,000
Because that's when the rubber hits the road in terms of what the main adoption that people will do is after the release.

23
00:02:53,000 --> 00:03:03,000
Suddenly, there will be increased activity, I think, around this because it'll become a much more real-world problem.

24
00:03:03,000 --> 00:03:16,000
Of course, it's great having as many packages as possible pre-release with showing zero data race errors, but I think that's when we'll really see people step up the activity.

25
00:03:16,000 --> 00:03:19,000
Yeah, it's pretty much still early adopters, isn't it?

26
00:03:19,000 --> 00:03:20,000
Yeah.

27
00:03:20,000 --> 00:03:30,000
The other thing I wanted to mention while we talk about this Swift 6 run, there is an issue we discovered and we're tracking this.

28
00:03:30,000 --> 00:03:37,000
It's issue 3233. That's almost four threes there in the issue number. We're getting close.

29
00:03:37,000 --> 00:03:44,000
We're reporting a slightly higher error count in some cases than there actually are.

30
00:03:44,000 --> 00:03:53,000
We've reported this and it's believed to be related to pre-concurrency errors being counted when they shouldn't be.

31
00:03:53,000 --> 00:04:03,000
Likely, there are pre-concurrency imports that should suppress any errors, but they might still be counted by the mechanism that we're using.

32
00:04:03,000 --> 00:04:09,000
So there's an internal compiler diagnosis reporting that we're using to report these numbers.

33
00:04:09,000 --> 00:04:14,000
We're not grepping through compiler output and counting errors that way.

34
00:04:14,000 --> 00:04:23,000
There's actually a mechanism to output JSON with compiler diagnostics and that's counting these Swift 6 errors.

35
00:04:23,000 --> 00:04:32,000
That's the number we're reporting and it looks like there might be a problem where this is over-reporting a slightly higher count.

36
00:04:32,000 --> 00:04:42,000
We've seen at least two packages where you don't get any Swift 6 warnings and yet the number reported is one and three or something like that.

37
00:04:42,000 --> 00:04:50,000
So it hopefully isn't a huge additional error count. That remains to be seen.

38
00:04:50,000 --> 00:04:53,000
In the cases that we've seen, it hasn't been huge.

39
00:04:53,000 --> 00:04:59,000
It certainly would prevent a package to be completely marked as error-free.

40
00:04:59,000 --> 00:05:02,000
And that's the problem, isn't it?

41
00:05:02,000 --> 00:05:08,000
That's that one number, but at least the error count number wouldn't be as dramatically impacted by that.

42
00:05:08,000 --> 00:05:14,000
And if your package is affected by this, please do let us know.

43
00:05:14,000 --> 00:05:27,000
It would be good to have a number of packages to investigate this with to make sure that this reporting lines up and we're reporting the thing that people also see when they build their packages.

44
00:05:27,000 --> 00:05:39,000
And if you have any doubt around how we actually run the builds, the build commands, the actual build commands that we're running is logged at the top of the package, the build details page.

45
00:05:39,000 --> 00:05:50,000
So if on the package page you click on the matrix, you go to the builds overview page and there you see the whole matrix, not just the condensed matrix, but every build that we make.

46
00:05:50,000 --> 00:06:00,000
And if you click on a cell through there, you land on the builds detail page and there we list the actual build that we run and the build log.

47
00:06:00,000 --> 00:06:03,000
And then you have all the details there to investigate further.

48
00:06:03,000 --> 00:06:11,000
And if you have any questions, just ping us and we'll take a look or help you find your way around those details.

49
00:06:11,000 --> 00:06:28,000
And while we're on the subject of data race safety and the user interface around data race safety, we just merged a change this afternoon that slightly changes the wording around the indicator we give for data race safety.

50
00:06:28,000 --> 00:06:32,000
Yes or no on data race safety in a package.

51
00:06:32,000 --> 00:06:55,000
It previously said safe from data race errors, which is a wonderful statement to be able to make, but we had some feedback, which made some really good points about the fact that all we're really doing there is we're saying that the Swift compiler is reporting zero data race safety errors.

52
00:06:55,000 --> 00:07:15,000
And no matter how you fix your data race safety errors, by either fixing them by changing your code to become data race safe or by suppressing them with something like an unchecked sendable or something like that, we still confidently say or said safe from data race errors, which was a little bit misleading.

53
00:07:15,000 --> 00:07:17,000
And it was good feedback.

54
00:07:17,000 --> 00:07:28,000
So we've just deployed a change this afternoon that now just says zero data race safety errors, which is a much more accurate way of describing it.

55
00:07:28,000 --> 00:07:33,000
And we've put a bit of information in the documentation around this feature.

56
00:07:33,000 --> 00:07:45,000
So there's an extra question in the frequently asked questions on the Ready for Swift 6 page and a little bit more information around the conditions that we're making that claim under.

57
00:07:45,000 --> 00:07:51,000
So just a little bit more accurate or a little bit less misleading, potentially.

58
00:07:51,000 --> 00:08:09,000
Yeah, it's actually, I just thought about this and it might be interesting in the future to see if there might be a mode where you build and actually can make stronger guarantees by looking if there's any unsafe shenanigans going on.

59
00:08:09,000 --> 00:08:20,000
And that might be interesting to see if that's actually possible to surface at some point as an extra label flag or something, a thing that gets reported up.

60
00:08:20,000 --> 00:08:22,000
Because I think that would be a great guarantee to have, right?

61
00:08:22,000 --> 00:08:32,000
If you're using packages that have no pre-concurrency imports or no unsafe sort of things, I wonder if that would be possible at some point.

62
00:08:32,000 --> 00:08:35,000
We'll just grab the source code for unchecked.

63
00:08:35,000 --> 00:08:38,000
Yeah, that'll work.

64
00:08:38,000 --> 00:08:41,000
Ship it.

65
00:08:41,000 --> 00:08:46,000
Yeah, join us for more ideas how to improve your projects.

66
00:08:46,000 --> 00:08:56,000
Right. There is another interesting bit of news that I saw fly by. It's actually been a couple of weeks now.

67
00:08:56,000 --> 00:09:01,000
I had this in the list of things to talk about for last time, but we ran long then.

68
00:09:01,000 --> 00:09:09,000
And this is from Filippo Valzorda. I saw this on Masternode a while ago.

69
00:09:09,000 --> 00:09:18,000
And I think Filippo is a former Google engineer and he's now maintaining security related open source projects written in Go.

70
00:09:18,000 --> 00:09:27,000
So it's not quite a Swift topic, but I think it sort of relates to what we do over here in Swift land as well.

71
00:09:27,000 --> 00:09:33,000
And he's sort of managed to get companies to pay him as an open source maintainer.

72
00:09:33,000 --> 00:09:40,000
And I suppose that's given what he's doing, you know, like he's maintaining security related projects.

73
00:09:40,000 --> 00:09:47,000
I think the most popular one is Age, which is a, I think, an encryption or a signing project.

74
00:09:47,000 --> 00:09:58,000
I'm a bit hazy on the details, but I imagine that's probably an easier pitch to get someone to pay you for that maintenance.

75
00:09:58,000 --> 00:10:03,000
But I wanted to bring this up because recently he published a blog post,

76
00:10:03,000 --> 00:10:10,000
made an announcement that he's converted this into a bigger project, which he called GeoMIS.

77
00:10:10,000 --> 00:10:20,000
And he's brought on board three other collaborators and they're maintaining now an ensemble of Go open source packages.

78
00:10:20,000 --> 00:10:26,000
And I thought it was really interesting because it's a long standing thing.

79
00:10:26,000 --> 00:10:30,000
I think we've even talked about this a couple of times on the podcast before.

80
00:10:30,000 --> 00:10:35,000
How does open source get funded?

81
00:10:35,000 --> 00:10:41,000
I mean, we're actually facing that problem or we have faced that problem. We're in a good place right now.

82
00:10:41,000 --> 00:10:45,000
But it's not the common case. Right.

83
00:10:45,000 --> 00:10:57,000
Everyone knows this XKCD comic where that lone person is maintaining critical infrastructure and is effectively doing it just for the fun of it.

84
00:10:57,000 --> 00:11:05,000
There's no contractual obligation. There's certainly no financial commitment by anyone for this kind of work.

85
00:11:05,000 --> 00:11:09,000
And nobody prepares you from the entitlement and abuse you'll get as well.

86
00:11:09,000 --> 00:11:16,000
Yes. God forbid stuff breaks. Right. Then suddenly you have everyone's attention.

87
00:11:16,000 --> 00:11:17,000
Yeah.

88
00:11:17,000 --> 00:11:20,000
Not in a good way.

89
00:11:20,000 --> 00:11:29,000
But, you know, every time that pops up, I wonder, is that the thing that might spark a bigger thing happening?

90
00:11:29,000 --> 00:11:33,000
And then I wonder, well, how is the biggest thing ever going to happen?

91
00:11:33,000 --> 00:11:36,000
What would that look like?

92
00:11:36,000 --> 00:11:48,000
I'm kind of hopeful that at some point, either a person like Filippo with enough clout manages to bring this up and sort of set an example that's then perhaps followed.

93
00:11:48,000 --> 00:11:59,000
Or maybe one or more companies with deep pockets set up sort of a foundation or something similar that will help fund open source projects, maybe in their area.

94
00:11:59,000 --> 00:12:04,000
So maybe by language, maybe by topic. I don't know what a good model would be.

95
00:12:04,000 --> 00:12:27,000
It feels like we're reaching the end of this process being workable, the way it's being run, that just people hope there's someone who doesn't need the financial support and can manage to maintain this open source software, which everyone uses.

96
00:12:27,000 --> 00:12:40,000
But we're just cruising on luck here, you know, like all these security issues happen and it's not the fault of the people, it's just they're spread thin and they get exploited.

97
00:12:40,000 --> 00:12:51,000
Right, last time, was it the XC thing where it was effectively social engineering that's exploiting the fact that someone is just spread too thin and is happy for someone to help.

98
00:12:51,000 --> 00:13:10,000
And unless there's another mechanism that actually makes this a job, where it's seen as a proper responsibility and maintained, managed like a job, doesn't make it 100% guaranteed that nothing happens, but at least gives you a fighting chance.

99
00:13:10,000 --> 00:13:16,000
Because the way this is working right now, I can't see this going on forever like this.

100
00:13:16,000 --> 00:13:38,000
Well, I think you say you can't see it going on forever like this. Unfortunately, I think I can see it going on forever because it needs that there have been enough catastrophic situations caused by this kind of problem that I think if there was going to be a fundamental change, we might have seen a fundamental change.

101
00:13:38,000 --> 00:14:05,000
And I'm not, I think this project that has been set up here is wonderful. And I hope and wish that we are at the end of what you say there. But I fear that we may not be because it's always going to be incredibly challenging to get a company to pay for something that they don't have to pay for.

102
00:14:05,000 --> 00:14:22,000
And the fact of it is that they don't have to pay for these things. And you look back at history and you look at the outcomes of these catastrophic errors. And yes, there are significant impacts to them.

103
00:14:22,000 --> 00:14:37,000
But everything always recovers and it goes back to the status quo. And by the time you'd get that funding request through, the panic's over, right? It's a fundamental problem, I think, with open source.

104
00:14:37,000 --> 00:14:55,000
And also with the way that we structure open source is that quite often open source projects start up as somebody's little pet project and they generally develop something because they have a need or an interest in it themselves.

105
00:14:55,000 --> 00:15:09,000
And then over time, if it becomes a successful open source project, then other people get involved. And sometimes what happens is that original maintainer no longer needs that project and kind of has mentally moved on from it.

106
00:15:09,000 --> 00:15:29,000
But they are tied to this kind of open source project that they founded. And I think it can just be so difficult to organize funding around that. And you're right that security related open source projects are the most likely to get funded.

107
00:15:29,000 --> 00:15:45,000
But I don't think it should only be the security related ones because there are enormous amount of product. I mean, you look at most Swift applications have some kind of dependency in them.

108
00:15:45,000 --> 00:15:56,000
And they rely, probably rely quite heavily on at least one dependency to do what they do, whether it's a server side Swift one, whether it's an iOS or a Mac app.

109
00:15:56,000 --> 00:16:05,000
And to make that decision to go, okay, well, I'm going to seek out the authors of this project and fund them.

110
00:16:05,000 --> 00:16:17,000
And it's not, and what I'm not talking about here is small independent developers. I'm talking about big companies. So what that takes is a developer to say, we're really, we're really dependent on this project.

111
00:16:17,000 --> 00:16:31,000
And then to raise that up in a big company to get money for it is not a trivial task. And so I think it's wonderful that they've managed to do this with the Go, I forget the name of the company, but the Go company that you were just talking about.

112
00:16:31,000 --> 00:16:41,000
But I do fear that, I do fear for whether it's possible for that to become a sustainable model.

113
00:16:41,000 --> 00:16:50,000
Yeah, I think some of it is around actually even pitching the thing and how would the transaction work, right?

114
00:16:50,000 --> 00:17:06,000
Because I think many open source projects aren't even set up to invoice that kind of thing or companies, because you know how purchase processes work in companies, sometimes it's easier to get to sign up for a service, you know, through a website rather than to make a one-off purchase.

115
00:17:06,000 --> 00:17:19,000
Some of it is just logistics around that kind of stuff. I do wonder if the increased sensitivity around software bill of materials might change that in some respect.

116
00:17:19,000 --> 00:17:34,000
Because, and what that is, is a software bill of materials is a list of all the dependencies that are being used to assemble a software project. And that's gotten some attention.

117
00:17:34,000 --> 00:17:57,000
I think it was even in the US somewhere, it's sort of like an official thing that's being looked at as a requirement, I think for government funded projects, which are obviously sensitive, especially in some areas around what's the input into the programs, software that's being built.

118
00:17:57,000 --> 00:18:08,000
And that's appearing there might raise some awareness even in other projects, well, what is it actually we pull in? And that has changed over time.

119
00:18:08,000 --> 00:18:18,000
So in the last iOS project that I was on, it was always a requirement to at least list all the open source projects in a view.

120
00:18:18,000 --> 00:18:29,000
So that was a first step that didn't actually happen before. I think it was always sort of a requirement, but never happened. And obviously, listing them in a screen isn't really a high bar.

121
00:18:29,000 --> 00:18:36,000
I mean, we're really just talking about giving credit, but it is a step towards raising awareness. Look, this is what we're using.

122
00:18:36,000 --> 00:18:48,000
And then the next step is, well, we're using this for free, we have no contractual relationship to these vendors, because that's what they are, they're third party vendors that we're using.

123
00:18:48,000 --> 00:18:53,000
And maybe if we want something from them, we should have one.

124
00:18:53,000 --> 00:19:07,000
And that might change and maybe start that conversation at some point. And I guess it'll always have to be, you know, sort of like an app store for open source software that'll probably have to form at some point,

125
00:19:07,000 --> 00:19:18,000
because no small third party library author will end up engaging with a big company and selling your maintenance or whatever.

126
00:19:18,000 --> 00:19:37,000
However, that's going to work like it has to be some aggregator that gets stuff together and then funnels, you know, is sort of the place where funding ends up and then gets distributed through some key towards the library authors.

127
00:19:37,000 --> 00:19:49,000
That's always in my mind. It can't be an end times end, you know, like end companies dealing with end maintainers and having all these relationships being formed.

128
00:19:49,000 --> 00:19:53,000
Yeah, and that's the whole idea behind this company is that you're not dealing with that.

129
00:19:53,000 --> 00:19:54,000
Exactly.

130
00:19:54,000 --> 00:20:04,000
You're not dealing with, like the company signs up to, I'm going to support some open source projects, and then it's the company that's responsible for determining how to distribute that money, which is the right way to do it.

131
00:20:04,000 --> 00:20:05,000
It's the right way to do it.

132
00:20:05,000 --> 00:20:06,000
Yeah, absolutely.

133
00:20:06,000 --> 00:20:23,000
And especially because I've come across situations where open source package authors, not specifically Swift, but open source authors, that step between not being able to accept money and being able to accept money, even if it's, you know, $1, is a huge step.

134
00:20:23,000 --> 00:20:24,000
Yeah.

135
00:20:24,000 --> 00:20:28,000
You've got to formalize your whole system for that.

136
00:20:28,000 --> 00:20:30,000
You know, maybe you have to make a company.

137
00:20:30,000 --> 00:20:33,000
Maybe you at least have to think about how that's going to work.

138
00:20:33,000 --> 00:20:35,000
Does it have its own bank account?

139
00:20:35,000 --> 00:20:42,000
Does it have, you know, all these questions are actually quite difficult, and it puts a lot of people who just got into it to write some open source code.

140
00:20:42,000 --> 00:20:49,000
It puts quite a lot of, I've come across people who just don't want to deal with that at all, and therefore that's the end of it.

141
00:20:49,000 --> 00:20:50,000
And that's fine.

142
00:20:50,000 --> 00:20:53,000
But a concept like this is really good.

143
00:20:53,000 --> 00:20:55,000
I just fear for it.

144
00:20:55,000 --> 00:21:09,000
On the subject of displaying your acknowledgements for open source libraries that you're using in your iOS and Mac apps, there are several packages in the Swift Package Index that will help you do that.

145
00:21:09,000 --> 00:21:10,000
Absolutely.

146
00:21:10,000 --> 00:21:25,000
So one is called Act Now List, or I guess it's Act No List, but it's by Vincent Terrain, and that's been around for eight years.

147
00:21:25,000 --> 00:21:37,000
So that's a very well-established project that will give you a view controller in an iOS application that will list all of your, gather all of the license agreements and then list them in a view controller.

148
00:21:37,000 --> 00:21:46,000
There's also one called License P-List by Mayasuki Ono that seems to do the same thing.

149
00:21:46,000 --> 00:21:54,000
I haven't used either of them, but I have manually put together that list many times in iOS apps.

150
00:21:54,000 --> 00:21:55,000
Nice.

151
00:21:55,000 --> 00:21:57,000
Yeah, is that a requirement or something?

152
00:21:57,000 --> 00:21:59,000
I vaguely recall this.

153
00:21:59,000 --> 00:22:05,000
It certainly was common recently, and stuff like that often doesn't happen on its own.

154
00:22:05,000 --> 00:22:13,000
It is a requirement of the open source licenses, but the other problem is that nobody is enforcing that.

155
00:22:13,000 --> 00:22:33,000
So it is purely based on your desire to do it rather than any kind of comeback from not doing it, because it's only the open source license agreements that you're breaking, which are very important, but there's no open source license police as far as I'm aware.

156
00:22:33,000 --> 00:22:36,000
So no App Store requirement? I vaguely remember.

157
00:22:36,000 --> 00:22:37,000
I don't think so.

158
00:22:37,000 --> 00:22:45,000
Okay, I might misremember. I'm not reading those terms frequently enough to actually know.

159
00:22:45,000 --> 00:22:51,000
If there is, it's certainly not something that the App Store review process actively checks for.

160
00:22:51,000 --> 00:22:58,000
Well, how would they even, well, I guess, I mean, you could perhaps at some level, but that's just way in the weeds.

161
00:22:58,000 --> 00:22:59,000
Yeah.

162
00:22:59,000 --> 00:23:00,000
Right.

163
00:23:00,000 --> 00:23:05,000
But yes, let's hope that you're right and I'm wrong.

164
00:23:05,000 --> 00:23:08,000
There's always hope.

165
00:23:08,000 --> 00:23:14,000
Well, you've sort of started the package recommendations already, I think. Are we at that stage?

166
00:23:14,000 --> 00:23:19,000
We've had two unofficial package recommendations already.

167
00:23:19,000 --> 00:23:22,000
It's a bumper bonus show.

168
00:23:22,000 --> 00:23:27,000
But yes, I can kick us off with my first package for the day.

169
00:23:27,000 --> 00:23:33,000
So my first package is called Easing by Pamel Sharanda.

170
00:23:33,000 --> 00:23:36,000
And I really like this package.

171
00:23:36,000 --> 00:23:40,000
It's a set of easing functions.

172
00:23:40,000 --> 00:23:46,000
So this is things like ease in, ease out that you might be familiar with from animations.

173
00:23:46,000 --> 00:23:55,000
But the package itself, as I understand it, is only providing the calculation.

174
00:23:55,000 --> 00:24:04,000
So you can give it some values and it will give you an output based on those values using an easing function.

175
00:24:04,000 --> 00:24:12,000
So, for example, you can say, give it a quadratic ease in and out equation.

176
00:24:12,000 --> 00:24:21,000
And you can then use that method that it provides to apply to any property in a view.

177
00:24:21,000 --> 00:24:35,000
So you can, for example, one of the sample codes that is in the readme file is taking a UI scroll view where the header is fully visible when the content offset is zero.

178
00:24:35,000 --> 00:24:40,000
So you have a header at the top of your scroll view when it's scrolled to the top.

179
00:24:40,000 --> 00:24:49,000
And as you scroll, when you get to 100 points of scrolling, it fades out over that point, which is easy enough to do in a linear fashion.

180
00:24:49,000 --> 00:24:54,000
But it allows you to add an easing function to that calculation.

181
00:24:54,000 --> 00:24:58,000
And so it's not something that you're just plugging into an animation framework.

182
00:24:58,000 --> 00:25:05,000
It is something that you are taking control of yourself and saying, given this value, put it through this easing function.

183
00:25:05,000 --> 00:25:10,000
And what's my actual value that I should be passing on to my user interface?

184
00:25:10,000 --> 00:25:30,000
And I really like that. And there's a great set of very comprehensive set of easing functions here, including bouncing and elastic and obviously kind of easing in and out and all the rest of it, quadratic and sine and all the rest of it.

185
00:25:30,000 --> 00:25:36,000
So lots and lots of different easing functions and a nice, interesting way to use them as well.

186
00:25:36,000 --> 00:25:42,000
Nice. Is that like SwiftUI, UIKit, Multiplatform?

187
00:25:42,000 --> 00:25:50,000
I think it will work with both because I think the example here was actually not even specific to...

188
00:25:50,000 --> 00:25:55,000
I think it might be a UI view that they're dealing with here, but they're not specific.

189
00:25:55,000 --> 00:25:56,000
It's really just the function.

190
00:25:56,000 --> 00:25:58,000
The library is purely dealing with the numbers.

191
00:25:58,000 --> 00:26:02,000
Yeah, exactly. And you can do with that what you want.

192
00:26:02,000 --> 00:26:06,000
Interesting. Nice. Right.

193
00:26:06,000 --> 00:26:13,000
My first package is called Swift Homomorphic Encryption and it's by Apple.

194
00:26:13,000 --> 00:26:18,000
It's a mouthful. It's a very interesting package that was recently announced on Swift.org.

195
00:26:18,000 --> 00:26:21,000
There's a blog post announcing it.

196
00:26:21,000 --> 00:26:36,000
And I found that fascinating and I had to read it up a bit, a little, what this actually means, what this is about.

197
00:26:36,000 --> 00:26:46,000
And it sounds like you can run this or that's what the claim of homomorphic encryption is, that you can encrypt something,

198
00:26:46,000 --> 00:26:56,000
then run computations on it and then decrypt it and you get the same result as if you'd run the computation on the original data.

199
00:26:56,000 --> 00:27:05,000
And what that means is you can send data to a service that then runs a computation and returns you a result.

200
00:27:05,000 --> 00:27:08,000
And you're never actually revealing your data.

201
00:27:08,000 --> 00:27:12,000
So it's not even temporarily decrypted on the host running the computation.

202
00:27:12,000 --> 00:27:22,000
And you can imagine how useful that is in a cloud environment where you send something off to a server and you can't be sure where that's running.

203
00:27:22,000 --> 00:27:29,000
And you wouldn't even want this to be just decrypted in RAM for the computation.

204
00:27:29,000 --> 00:27:35,000
And this sounds a bit like magic and it's like, how can this even work?

205
00:27:35,000 --> 00:27:38,000
And I read up a little on this.

206
00:27:38,000 --> 00:27:41,000
So there are some caveats around this.

207
00:27:41,000 --> 00:27:50,000
There are apparently different levels of homomorphic encryption and they determine what operations you can run and in some cases even how often.

208
00:27:50,000 --> 00:27:59,000
And I guess that depends on how the pre-encoding of the data and the actual encryption of the data gets sort of, I mean, in my mind is mangled.

209
00:27:59,000 --> 00:28:02,000
You have to be careful what operations you can run.

210
00:28:02,000 --> 00:28:08,000
This is due to the mathematical background of this.

211
00:28:08,000 --> 00:28:13,000
This deals with maps and similar regions and it's all quite complicated.

212
00:28:13,000 --> 00:28:25,000
But in a nutshell, and I'll link to or we'll link to another blog post that explains this a little better in easier terms how this actually works.

213
00:28:25,000 --> 00:28:28,000
But the concept really is this.

214
00:28:28,000 --> 00:28:44,000
You can send stuff off that is pre-encrypted and can't be looked at and can't be computed with and then you get the results and you decrypt it and you get your result as if you'd run it locally.

215
00:28:44,000 --> 00:28:47,000
I've actually tried this with the package.

216
00:28:47,000 --> 00:28:58,000
And that's why if I sound a bit unsure how this works is because my attempts to actually make this work locally were sort of mixed.

217
00:28:58,000 --> 00:29:03,000
And I'm not sure, I mean, one thing is for sure, I don't know what I'm doing.

218
00:29:03,000 --> 00:29:14,000
So this package has all sorts of parameters that you can configure and the example has an encoding scheme set up and there's all sorts of knobs you can turn to set this up.

219
00:29:14,000 --> 00:29:25,000
And I think this is mainly dealing with what kind of homomorphic encryption you're setting up to ensure what kind of operations you can support on the other end.

220
00:29:25,000 --> 00:29:28,000
And I think that's what might be happening here.

221
00:29:28,000 --> 00:29:39,000
So what I've tried is I took the example, I encrypted some numbers and then I added up the encrypted values and then I decrypted it.

222
00:29:39,000 --> 00:29:47,000
And it seems to work for numbers that are small enough and bigger numbers look like they're overflowing or something.

223
00:29:47,000 --> 00:29:49,000
There must be something happening with the decryption.

224
00:29:49,000 --> 00:29:57,000
So they return wrong results but many of them, the small numbers actually do return correct results.

225
00:29:57,000 --> 00:30:05,000
If you're listening to this and you actually know what's going on or what I did wrong, I'd be really interested to hear about this.

226
00:30:05,000 --> 00:30:17,000
But I thought it would be really interesting to talk about this package and present it even though I didn't manage to work with it correctly because it's obviously a thing that works.

227
00:30:17,000 --> 00:30:24,000
It's used by Apple in their live caller ID lookup feature in iOS 18.

228
00:30:24,000 --> 00:30:28,000
So it's clearly user error that I'm not getting the right thing.

229
00:30:28,000 --> 00:30:37,000
And I think it might be interesting, I thought it would be interesting to talk about it anyway, even though in my testing I can't quite grasp how this works.

230
00:30:37,000 --> 00:30:45,000
But it's certainly a very, very interesting package and I love that it's been open sourced by Apple for us to play around.

231
00:30:45,000 --> 00:30:56,000
I'm so glad that you tackled that one because I saw that blog post too and I read the first couple of paragraphs of it and thought this is a blog post for other people.

232
00:30:56,000 --> 00:31:11,000
Yeah, I mean, I really was on the verge of just not talking about it, but I thought well, it can't be just because I can't deal with it that it shouldn't get a mention at least.

233
00:31:11,000 --> 00:31:19,000
And there's also one thing I should mention that's absolutely a useful takeaway from this package, which actually has nothing to do with the package itself.

234
00:31:19,000 --> 00:31:23,000
But it's something I learned and it's going to be useful for everyone.

235
00:31:23,000 --> 00:31:29,000
And this is the experimental command to install a package executable.

236
00:31:29,000 --> 00:31:45,000
Did you know this exists? So you can run swift package experimental dash install and then this does the same as build, but it puts the executable in your home directory in .swiftpm dash bin.

237
00:31:45,000 --> 00:31:49,000
And if you add that to your path, you can then run the executable.

238
00:31:49,000 --> 00:31:55,000
So it's effectively like mint. People might know this little tool that did the same thing.

239
00:31:55,000 --> 00:32:04,000
Mint is a tool that is actually a swift executable that you once installed can use to install any swift executable from a package into your system.

240
00:32:04,000 --> 00:32:08,000
And this is a experimental feature in .swiftpm.

241
00:32:08,000 --> 00:32:16,000
So I thought at the very least one takeaway for this package might be for people that this exists.

242
00:32:16,000 --> 00:32:22,000
Yes, I didn't know that exists. And that is a much needed, because there's no standard way to do it.

243
00:32:22,000 --> 00:32:25,000
Yes, there's mint. Yes, you could also make yourself a brew package.

244
00:32:25,000 --> 00:32:30,000
Some people just put a make file in there and have a make install or something like that.

245
00:32:30,000 --> 00:32:33,000
But it's all very ad hoc at the moment.

246
00:32:33,000 --> 00:32:42,000
And I'm very happy to see Swift tackle this problem because Swift command line tools are great.

247
00:32:42,000 --> 00:32:46,000
And this is one of the problems with people using them.

248
00:32:46,000 --> 00:32:54,000
Yeah, absolutely. Yeah. Yeah. I do tend to write more and more stuff as Swift commands like that used to be shell scripts.

249
00:32:54,000 --> 00:33:01,000
And stuff like this will make it so much easier to bring that into a system and to easily update it and stuff like that.

250
00:33:01,000 --> 00:33:03,000
So really nice.

251
00:33:03,000 --> 00:33:07,000
The thing that did it for me is argument parser.

252
00:33:07,000 --> 00:33:12,000
Argument parser is so good. Oh, yes. And so usable.

253
00:33:12,000 --> 00:33:19,000
And so it's so trivial to make a little command line tool that behaves exactly how you would want it to behave with Swift argument parser.

254
00:33:19,000 --> 00:33:26,000
That it takes a lot of that overhead away from creating that tool.

255
00:33:26,000 --> 00:33:34,000
And I'm the same as you. I reach for Swift now where I would previously have reached for Ruby for that kind of stuff.

256
00:33:34,000 --> 00:33:37,000
Yeah, absolutely.

257
00:33:37,000 --> 00:33:41,000
Yet another bonus package recommendation there.

258
00:33:41,000 --> 00:33:44,000
Argument parser.

259
00:33:44,000 --> 00:33:52,000
My next package is called Cloak String Macro by Lucas Gergel.

260
00:33:52,000 --> 00:33:57,000
And this, as you might imagine from the name, is a macro.

261
00:33:57,000 --> 00:34:07,000
And so before I talk about this, I'll add a disclaimer, which is you should never put API keys in your binary.

262
00:34:07,000 --> 00:34:18,000
So if you find yourself putting a constant string in your application that contains an API key, you are in inverted commas doing it wrong.

263
00:34:18,000 --> 00:34:28,000
And yet at the same time, for those situations where you have to do that, this is a potential way to do it slightly more safely.

264
00:34:28,000 --> 00:34:36,000
Like obviously, if you're putting an API key or any other secret in your application that ships as a binary onto someone's disk,

265
00:34:36,000 --> 00:34:42,000
then it is at risk of being discovered. And you shouldn't do that for anything really, really important.

266
00:34:42,000 --> 00:34:46,000
But there are also times when less important strings are necessary.

267
00:34:46,000 --> 00:34:57,000
And the disadvantage of putting a string in there is there are lots of tools that can very easily gather all the strings out of a binary,

268
00:34:57,000 --> 00:35:03,000
because of the way binaries are constructed, all the strings tend to be stuck together in a big strings block.

269
00:35:03,000 --> 00:35:07,000
And it's very easy to just grab all the strings out.

270
00:35:07,000 --> 00:35:15,000
And even if you do things like chop it up and store each different bit separately, like there's a big kind of code smell there.

271
00:35:15,000 --> 00:35:21,000
But what this does is it takes with a macro, which is this is a great use of macro actually,

272
00:35:21,000 --> 00:35:31,000
it takes your secret API key and splits it and produces a data struct that is initialized with bytes of data

273
00:35:31,000 --> 00:35:38,000
and just makes that a whole lot harder to find, not impossible to find, should make sure that's very clear,

274
00:35:38,000 --> 00:35:42,000
but certainly a lot more difficult to find, because it's no longer going to be in that strings block,

275
00:35:42,000 --> 00:35:47,000
no longer going to be trivial to get it out of an application.

276
00:35:47,000 --> 00:35:55,000
And so I certainly have come across situations where storing this kind of stuff in an application is the way to do it,

277
00:35:55,000 --> 00:36:01,000
especially if normally it comes down to if you're doing something that requires an API that doesn't have an account system,

278
00:36:01,000 --> 00:36:09,000
so you can't have a login where you could provide the keys on login, then this is normally where this happens.

279
00:36:09,000 --> 00:36:16,000
Very nice. I believe we had a similar package in the recommendations in the past, but I think it's really...

280
00:36:16,000 --> 00:36:17,000
Oh, did we?

281
00:36:17,000 --> 00:36:21,000
Yeah, but I think it's nice to bring this up again and again,

282
00:36:21,000 --> 00:36:31,000
because macros are really nice with these kinds of things, embedding stuff or adding functionality, that is really easy to add.

283
00:36:31,000 --> 00:36:34,000
So that's CloakedStringMacro by Lukas Gergel.

284
00:36:34,000 --> 00:36:42,000
Nice. My second package recommendation is called KeyColor by Anton Herstand.

285
00:36:42,000 --> 00:36:51,000
And Anton's package is one of those that can be described with a simple image, which is unfortunate for a podcast.

286
00:36:51,000 --> 00:37:03,000
But if you look at the readme, it'll be very clear what this does, because it does come with some images, really nice images.

287
00:37:03,000 --> 00:37:07,000
So just to describe this as an image and below the image,

288
00:37:07,000 --> 00:37:13,000
like there's an image of an orange on a blue background and below the orange are three colored dots.

289
00:37:13,000 --> 00:37:20,000
And you see a yellow, you see a blue and you see a bit of a red because that's from the center of the orange.

290
00:37:20,000 --> 00:37:28,000
So you can pick out dominant colors from an image via this package, which is really nice.

291
00:37:28,000 --> 00:37:38,000
If, for instance, you want to frame it or, you know, pick up font colors that go with the image that you're annotating or something like that.

292
00:37:38,000 --> 00:37:47,000
And if I remember correctly, you can also. Yeah, there's a certain number of colors you can choose.

293
00:37:47,000 --> 00:37:51,000
It's not just one. There's a range of colors you can pick.

294
00:37:51,000 --> 00:38:01,000
And I suppose that sort of intelligently picks, you know, the dominant colors, shifting them around a bit, depending on how many you pick.

295
00:38:01,000 --> 00:38:12,000
So I think that's a really nice package because it's sort of a problem that might seem simple if you think about it, but then turns out probably really hard.

296
00:38:12,000 --> 00:38:22,000
I remember trying way, way back to frame an image with the sort of corner colors.

297
00:38:22,000 --> 00:38:33,000
So sort of like think of your music player where the album art sits in the center and then the whole background of the screen is sort of continuously.

298
00:38:33,000 --> 00:38:40,000
And it seems like the album art is sort of crafted onto this color, you know, it all matches up.

299
00:38:40,000 --> 00:38:49,000
And I tried taking like the average from all the corner pixels and it never quite looked quite right because, you know,

300
00:38:49,000 --> 00:38:54,000
averages are problematic because they get shifted by one thing that's an outlier.

301
00:38:54,000 --> 00:38:57,000
And then suddenly everything is kind of off.

302
00:38:57,000 --> 00:39:06,000
And so a package that deals with that and looking, I mean, obviously the examples are picked to demonstrate the capabilities of the package,

303
00:39:06,000 --> 00:39:12,000
but it'll be easy enough to try with a few images to see how well that works.

304
00:39:12,000 --> 00:39:18,000
It's certainly something that's going to get you started if you want to do something like that.

305
00:39:18,000 --> 00:39:21,000
We had a package just a couple of weeks ago on the podcast.

306
00:39:21,000 --> 00:39:27,000
In fact, I think it might have been in the last episode, which was similar in it was the package BlurHash,

307
00:39:27,000 --> 00:39:33,000
which would take a similar thing where it could make an image and create a mesh gradient.

308
00:39:33,000 --> 00:39:34,000
All right.

309
00:39:34,000 --> 00:39:35,000
Yes.

310
00:39:35,000 --> 00:39:37,000
Gave you the essence of that image.

311
00:39:37,000 --> 00:39:38,000
Yeah.

312
00:39:38,000 --> 00:39:40,000
The essence of that image in a gradient.

313
00:39:40,000 --> 00:39:50,000
So, yeah, there's lots of lots of techniques out there to get the right colors and to get the right mechanism to represent something that would look good with an image,

314
00:39:50,000 --> 00:39:53,000
you know, and yeah, it's a good technique.

315
00:39:53,000 --> 00:39:54,000
It's a clever technique.

316
00:39:54,000 --> 00:39:55,000
Really nice.

317
00:39:55,000 --> 00:39:56,000
Yeah.

318
00:39:56,000 --> 00:39:58,000
So that's KeyColor by Anton Hest and...

319
00:39:58,000 --> 00:40:00,000
Fabulous.

320
00:40:00,000 --> 00:40:05,000
My last package is one that I also haven't looked at in detail yet,

321
00:40:05,000 --> 00:40:10,000
but it's interesting enough that I want to at least give it a mention.

322
00:40:10,000 --> 00:40:15,000
It's called Lightpack and it's written by Daniel Noskin.

323
00:40:15,000 --> 00:40:20,000
And I really like the concept of what this does.

324
00:40:20,000 --> 00:40:29,000
So there's a lot of things you can do with some of the open source and freely available large language models that are available,

325
00:40:29,000 --> 00:40:34,000
like Lama, which I think is by Meta, and Gemma.

326
00:40:34,000 --> 00:40:39,000
I'm not sure who Gemma is by, but I know it's also openly available.

327
00:40:39,000 --> 00:40:41,000
And the description of this package is very simple.

328
00:40:41,000 --> 00:40:50,000
It says run Lama 3.1 and Gemma 2 locally in your iOS and MacOS apps in three lines of code, open source, offline and private.

329
00:40:50,000 --> 00:40:53,000
And that's a very compelling description for a package.

330
00:40:53,000 --> 00:40:59,000
If you can ship something, obviously, we've got Apple Intelligence coming later this year or maybe next year.

331
00:40:59,000 --> 00:41:14,000
And if you can ship something that uses this kind of large language model inside your application that doesn't need network connectivity and doesn't need API costs and all the rest of it,

332
00:41:14,000 --> 00:41:19,000
there are lots of lots of uses for that in many applications.

333
00:41:19,000 --> 00:41:33,000
The reason I'm a little unsure about this is that I'm not quite sure why you need an API key from this lightpack.run site, which Daniel is running.

334
00:41:33,000 --> 00:41:38,000
Because if you look at the site, so it's at lightpack.run, there's very little information.

335
00:41:38,000 --> 00:41:45,000
In fact, there's almost no information on the homepage about why you need an account, why you need an API key.

336
00:41:45,000 --> 00:41:54,000
And so I have some questions around why an API key is necessary if it is on device and secure and private and all those things that it claims.

337
00:41:54,000 --> 00:41:59,000
So I just have a question mark around why that's necessary, how that works.

338
00:41:59,000 --> 00:42:07,000
But I think if this is something you're looking at wanting to do in your application, I would certainly give this a check out.

339
00:42:07,000 --> 00:42:18,000
And just to be completely fair to Daniel, I think the most likely reason is that there's no information on the website is that it's just not there yet.

340
00:42:18,000 --> 00:42:23,000
And there is an email address for Daniel at the bottom of the page.

341
00:42:23,000 --> 00:42:30,000
And so if you are thinking of using it, I'm confident that he would respond to an email.

342
00:42:30,000 --> 00:42:40,000
But yeah, I think it's a powerful idea. And if this is the way to do it, then yeah, I think this looks great.

343
00:42:40,000 --> 00:42:45,000
Certainly, the code sample of using it is trivially simple.

344
00:42:45,000 --> 00:42:51,000
Well, it has to require a download of the models, right? And aren't they huge?

345
00:42:51,000 --> 00:42:55,000
Even in the Lama case, which I believe is smaller than normal, but...

346
00:42:55,000 --> 00:42:59,000
And maybe that's what the API key is for. Maybe it's for downloading the models, possibly.

347
00:42:59,000 --> 00:43:05,000
So there's a recommendation just with a little question mark on the end of it.

348
00:43:05,000 --> 00:43:09,000
Great. Well, I don't have a third one today.

349
00:43:09,000 --> 00:43:12,000
Well, then that's the end of the podcast.

350
00:43:12,000 --> 00:43:19,000
That's the end of that, then.

351
00:43:19,000 --> 00:43:23,000
Actually, I do have one more thing to say before we sign off today,

352
00:43:23,000 --> 00:43:30,000
which is I'm planning to do something a little different with the production of this podcast.

353
00:43:30,000 --> 00:43:41,000
So look out in your podcast player for whether this podcast may have chapters so that you can skip through the news into the package recommendations.

354
00:43:41,000 --> 00:43:47,000
And potentially even between each package recommendation, we'll see how my experimentation goes.

355
00:43:47,000 --> 00:43:54,000
If your podcast player is not showing any chapters, then it went badly.

356
00:43:54,000 --> 00:43:56,000
Stay tuned.

357
00:43:56,000 --> 00:44:00,000
But I'm certainly planning to do that with this podcast episode.

358
00:44:00,000 --> 00:44:03,000
And if it works out from here on out.

359
00:44:03,000 --> 00:44:14,000
So there's a bit of suspense that you will, you as the audience, already know the outcome of this that I don't yet know the outcome of.

360
00:44:14,000 --> 00:44:19,000
But until then, until next time, we will say goodbye for now.

361
00:44:19,000 --> 00:44:23,000
And we'll speak to you next time. Until next time. Bye bye. Bye bye.