Navigated to 61: People have been working on it for ten years - Transcript

61: People have been working on it for ten years

Episode Transcript

1 00:00:00,001 --> 00:00:06,000 So I feel slightly outnumbered today on today's episode of the podcast, 2 00:00:06,000 --> 00:00:12,800 because, well, for something a little novel that we used to do at the very beginning, 3 00:00:12,800 --> 00:00:15,300 but we haven't done for a little while, is we have a guest on the podcast. 4 00:00:15,300 --> 00:00:23,100 But before we introduce our guest, I'm actually going to pass the baton to Sven, 5 00:00:23,100 --> 00:00:27,000 because I feel a little outnumbered in people who speak French today. 6 00:00:27,000 --> 00:00:33,000 And I'm not going to attempt the pronunciation of our guest's name. 7 00:00:33,000 --> 00:00:35,200 So, Sven, would you like to introduce our guest? 8 00:00:35,200 --> 00:00:38,800 I was wracking my brain while you were talking, thinking, 9 00:00:38,800 --> 00:00:40,800 what would Marc and I have in common? 10 00:00:40,800 --> 00:00:43,200 And I'm giving away part of his name already. 11 00:00:43,200 --> 00:00:48,900 It's Marc Brudomont, who's joining us today to talk about Swift on Android. 12 00:00:48,900 --> 00:00:54,500 You've completely dumped this introduction on me, Dave. Thank you. 13 00:00:54,500 --> 00:01:01,000 Well, I didn't want to embarrass myself with my attempt at the pronunciation, 14 00:01:01,000 --> 00:01:04,000 because I am not a French speaker, unfortunately. 15 00:01:04,000 --> 00:01:05,600 I wish I was, but I'm not. 16 00:01:05,600 --> 00:01:08,700 Hello, everyone, and fantastic pronunciation, Sven. 17 00:01:08,700 --> 00:01:11,000 It's better than I think I've ever heard it. 18 00:01:11,000 --> 00:01:11,900 Thank you. 19 00:01:11,900 --> 00:01:13,500 I was also very impressed. 20 00:01:13,500 --> 00:01:19,200 I knew the reason I dumped it on Sven was I knew he'd do a good job with that. 21 00:01:19,200 --> 00:01:23,900 But welcome. Thank you so much for joining us. 22 00:01:23,900 --> 00:01:25,300 Yeah, thank you for having me. 23 00:01:25,300 --> 00:01:33,200 So, I think the best place to get started is for you just to give a little introduction of who you are and what you do. 24 00:01:33,200 --> 00:01:38,400 Yeah, okay. Well, my name is Marc Brudomont, as we would say in English. 25 00:01:38,400 --> 00:01:42,300 And yeah, I am a developer. 26 00:01:42,300 --> 00:01:46,700 I've developed in a wide variety of languages and technologies over my career. 27 00:01:46,700 --> 00:01:52,600 But past, you know, 15 odd years, I've been predominantly an iOS developer. 28 00:01:52,600 --> 00:01:57,600 And I've started a company a couple of years ago called Skip. 29 00:01:57,600 --> 00:02:08,100 And the vision is to enable people to write their applications in Swift and be able to deploy them to both iOS and Android. 30 00:02:08,100 --> 00:02:13,700 It's really nice to see Swift growing into multiple other platforms. 31 00:02:13,700 --> 00:02:23,800 And it will be no surprise that we chatted with Marc before we added Android support to Swift Package Index, 32 00:02:23,800 --> 00:02:26,700 which we did a couple of months ago now. 33 00:02:26,700 --> 00:02:42,300 Because Marc and the Skip Tools team had made an independent website that was starting to test compatibility with Android packages 34 00:02:42,300 --> 00:02:45,400 or Swift packages compatibility with Android. 35 00:02:45,400 --> 00:02:47,900 And you were running that as a separate site, weren't you? 36 00:02:47,900 --> 00:02:50,900 Yeah, yeah, yeah. It was a Swift Everywhere. 37 00:02:50,900 --> 00:02:56,900 And it was just sort of running GitHub Actions that was more or less trolling through, you know, the popular packages 38 00:02:56,900 --> 00:03:00,500 and seeing does this build for Android? And if not, what are the errors? 39 00:03:00,500 --> 00:03:06,800 And then very often I would go through and I would try to resolve the errors and submit pull requests to the projects. 40 00:03:06,800 --> 00:03:14,100 And it was kind of a personal project to be able to promote the usage of the Swift Android SDK 41 00:03:14,100 --> 00:03:20,500 and be able to kind of build up more compatibility with some of the popular projects out there. 42 00:03:20,500 --> 00:03:28,100 And as you can now see on the site, we do have, well, we actually added two platforms at the same time. 43 00:03:28,100 --> 00:03:32,100 We added both Android and WASM compatibility checking. 44 00:03:32,100 --> 00:03:37,100 But just to stick on the Android for a little bit, and we'll talk more broadly in a second, 45 00:03:37,100 --> 00:03:46,600 but apart from checking the build logs that we do publish when we do all our platform builds, 46 00:03:46,600 --> 00:03:49,600 so if you haven't seen this feature of the Swift Package Index, 47 00:03:49,600 --> 00:03:54,600 if you look at the full build results of any package, you can then click through to the build log. 48 00:03:54,600 --> 00:04:00,600 And if there was a failed build, we will attempt to show you the build log. 49 00:04:00,600 --> 00:04:05,100 So apart from looking at those logs, is there anything that package authors can do 50 00:04:05,100 --> 00:04:11,100 to help themselves become more compatible with Android? 51 00:04:11,100 --> 00:04:17,600 Yeah, well, in general, the first step, so to step back a little bit, 52 00:04:17,600 --> 00:04:22,100 the Swift Android SDK is a cross-compilation SDK. 53 00:04:22,100 --> 00:04:27,600 So it's similar to the Static Linux, the MUSEL SDK and the WASM SDK. 54 00:04:27,600 --> 00:04:35,600 And it's a SDK that adds on to the host tool chain in order to allow you to build on a host platform, 55 00:04:35,600 --> 00:04:41,100 in other words, Mac or Linux or Windows, for another platform. 56 00:04:41,100 --> 00:04:46,600 So for example, with the Static Linux SDK, you can build on macOS for Linux. 57 00:04:46,600 --> 00:04:55,600 And with the Android SDK, you can build on macOS or Windows or Linux and cross-compile to Android. 58 00:04:55,600 --> 00:05:05,600 And in general, building for Android, you run into a lot of the similar issues as you would building for Linux. 59 00:05:05,600 --> 00:05:12,600 Very often, if there's like a low-level libc kind of function or something like that you're using, 60 00:05:12,600 --> 00:05:22,600 where maybe you would import Darwin on macOS or iOS, you would need to import glibc on Linux. 61 00:05:22,600 --> 00:05:28,600 That's usually with a conditional like if can import Darwin, if can import glibc. 62 00:05:28,600 --> 00:05:31,600 Android adds another one to that, which is Android. 63 00:05:31,600 --> 00:05:40,600 So you can cover a huge swath of those sorts of issues by just doing, you know, if can import this, if can import that, 64 00:05:40,600 --> 00:05:42,600 and then conditionally importing them. 65 00:05:42,600 --> 00:05:49,600 Generally speaking, if your package can compile for Linux, it's almost certainly going to be a pretty short, 66 00:05:49,600 --> 00:05:52,600 you know, small amount of work in order to get to build for Android. 67 00:05:52,600 --> 00:05:58,600 You're actually getting at a question that was sort of forming in my head as you two were talking, 68 00:05:58,600 --> 00:06:02,600 is how different is the Android SDK to Linux actually? 69 00:06:02,600 --> 00:06:07,600 If you were to boil it down, it sounds like it's almost as if there was a different kind of, 70 00:06:07,600 --> 00:06:11,600 you know, we have this Muzzle and glibc types of Linux. 71 00:06:11,600 --> 00:06:15,600 Is Android sort of, could you consider it to be a variant kind of like those? 72 00:06:15,600 --> 00:06:20,600 Yeah, yeah. So Android is Linux. It's just not GNU Linux. 73 00:06:20,600 --> 00:06:23,600 They have a different libc, they call it bionic. 74 00:06:23,600 --> 00:06:24,600 Yeah. 75 00:06:24,600 --> 00:06:28,600 And it's pretty compatible. Like they have almost all the same functions. 76 00:06:28,600 --> 00:06:34,600 You know, you can call abs and cosine and, you know, fopen, fclose, things like that. 77 00:06:34,600 --> 00:06:39,600 But generally speaking, it is not exactly the same. 78 00:06:39,600 --> 00:06:45,600 That's why you have a different set of headers that you import for the kind of low-level stuff. 79 00:06:45,600 --> 00:06:51,600 And so, yeah, it's very similar to sort of the difference between the static Linux SDK 80 00:06:51,600 --> 00:06:57,600 and actually compiling for Linux, where in one you import glibc and another you import Muzzle. 81 00:06:57,600 --> 00:07:03,600 And so, I mean, was there a particular itch you wanted to scratch yourself 82 00:07:03,600 --> 00:07:06,600 when you started delving into Swift on Android? 83 00:07:06,600 --> 00:07:11,600 What was sort of the motivation for you to try and do this? 84 00:07:11,600 --> 00:07:16,600 Well, the overarching goal is essentially to be able to, you know, 85 00:07:16,600 --> 00:07:21,600 the holy grail of mobile app development is to be able to use the same language 86 00:07:21,600 --> 00:07:24,600 to build an application for both platforms. 87 00:07:24,600 --> 00:07:31,600 And this is something that, you know, I have always been dissatisfied with the current state of affairs. 88 00:07:31,600 --> 00:07:35,600 You know, there's been a lot of iterations of this sort of thing, you know, 89 00:07:35,600 --> 00:07:38,600 in the olden days we had, you know, like Cordova and things like that 90 00:07:38,600 --> 00:07:42,600 that were just sort of like, you know, web views that you can code in JavaScript. 91 00:07:42,600 --> 00:07:46,600 More recently, the popular packages are things like Flutter and React Native 92 00:07:46,600 --> 00:07:51,600 where you, you know, write your app in Dart or JavaScript. 93 00:07:51,600 --> 00:07:54,600 But these all have, you know, a tremendous number of shortcomings 94 00:07:54,600 --> 00:07:57,600 that I think are pretty well understood. 95 00:07:57,600 --> 00:08:02,600 And they don't really embrace the native platform APIs. 96 00:08:02,600 --> 00:08:08,600 So, you know, the very high level goal was we want to allow you to write an application 97 00:08:08,600 --> 00:08:10,600 in a single language. 98 00:08:10,600 --> 00:08:13,600 And we love Swift. Swift is a fantastic language. 99 00:08:13,600 --> 00:08:16,600 We think it's ideal for application development. 100 00:08:16,600 --> 00:08:22,600 You know, they say it's, you know, all the ease of Java with all the efficiency of C. 101 00:08:22,600 --> 00:08:25,600 It's really ideal for this scenario. 102 00:08:25,600 --> 00:08:30,600 So that's really where we come from is we want to enable people to build their applications 103 00:08:30,600 --> 00:08:34,600 for the two major mobile operating systems out there. 104 00:08:34,600 --> 00:08:37,600 And everything else is really a result of that. 105 00:08:37,600 --> 00:08:41,600 You know, the whole joining the Android workgroup and all our iterations on the SDK 106 00:08:41,600 --> 00:08:46,600 and the tool chain and all of that is in service of this larger goal. 107 00:08:46,600 --> 00:08:49,600 And how practical is that today? 108 00:08:49,600 --> 00:08:51,600 It's very practical. 109 00:08:51,600 --> 00:08:57,600 People are using skip to build and ship applications, you know, currently. 110 00:08:57,600 --> 00:09:01,600 It does all work the sort of official-- 111 00:09:01,600 --> 00:09:07,600 So we ourselves, skip, are publishing our own tool chain right now, our own SDK, 112 00:09:07,600 --> 00:09:12,600 that is essentially the exact same SDK that is eventually going to be the official one 113 00:09:12,600 --> 00:09:15,600 that's published on swift.org. 114 00:09:15,600 --> 00:09:18,600 And we also have a lot of tooling that is built on top of it 115 00:09:18,600 --> 00:09:23,600 because just having a cross-compilation SDK is only one small real piece 116 00:09:23,600 --> 00:09:27,600 of the whole picture of actually building an application with, you know, 117 00:09:27,600 --> 00:09:30,600 graphical elements and integration with system APIs and things like that. 118 00:09:30,600 --> 00:09:31,600 Of course, yeah. 119 00:09:31,600 --> 00:09:35,600 But, yeah, no, it's up and running today. 120 00:09:35,600 --> 00:09:37,600 Things work really well. 121 00:09:37,600 --> 00:09:39,600 There's kind of two modes that we run in. 122 00:09:39,600 --> 00:09:42,600 We have something called skip light, which was our first iteration before we had 123 00:09:42,600 --> 00:09:48,600 the whole Android tool chain, where instead of actually compiling your Swift on Android, 124 00:09:48,600 --> 00:09:51,600 we transpile the source language to Kotlin, 125 00:09:51,600 --> 00:09:55,600 which is Android's sort of its own native development language. 126 00:09:55,600 --> 00:09:56,600 Right. 127 00:09:56,600 --> 00:10:00,600 And then that has really evolved into the current offering, 128 00:10:00,600 --> 00:10:03,600 which is called skip fuse, which takes those two concepts, 129 00:10:03,600 --> 00:10:06,600 the transpilation in order to integrate with Kotlin APIs, 130 00:10:06,600 --> 00:10:10,600 plus the native Android SDK, and bridges them all together 131 00:10:10,600 --> 00:10:14,600 so that you have one-- you have all the benefits of writing all your applications 132 00:10:14,600 --> 00:10:18,600 on Swift, but you can still talk to all of the Android APIs, 133 00:10:18,600 --> 00:10:20,600 which are all in Java and Kotlin. 134 00:10:20,600 --> 00:10:21,600 Right. 135 00:10:21,600 --> 00:10:23,600 So actually-- and I wanted to clarify that. 136 00:10:23,600 --> 00:10:27,600 When you use Swift on Android to develop an app, you are actually-- 137 00:10:27,600 --> 00:10:29,600 like the GUI is a native GUI, right? 138 00:10:29,600 --> 00:10:36,600 It's not like Qt on Mac that sort of has UI elements that look Mac-like 139 00:10:36,600 --> 00:10:39,600 but aren't actually-- to my knowledge. 140 00:10:39,600 --> 00:10:41,600 Last I checked, it was sort of a different-- 141 00:10:41,600 --> 00:10:46,600 it was made to look like Mac UI but wasn't truly Mac, 142 00:10:46,600 --> 00:10:48,600 was redrawn effectively. 143 00:10:48,600 --> 00:10:53,600 But this you're saying is actually-- this is using actual Android native UI elements. 144 00:10:53,600 --> 00:10:54,600 Is that right? 145 00:10:54,600 --> 00:10:55,600 Yeah. 146 00:10:55,600 --> 00:10:59,600 So these are sort of genuine native user interfaces on both platforms. 147 00:10:59,600 --> 00:11:03,600 And that's the thing that we feel like no one has really succeeded with. 148 00:11:03,600 --> 00:11:06,600 You look at Flutter apps and things like that, 149 00:11:06,600 --> 00:11:09,600 and they draw the pixel, they paint the pixels onto a canvas, 150 00:11:09,600 --> 00:11:13,600 and they kind of mimic iOS with their Cupertino theme, 151 00:11:13,600 --> 00:11:16,600 and they mimic Android with their Material theme. 152 00:11:16,600 --> 00:11:23,600 But pretty quickly, even a non-technical user identifies the scrolling is not-- 153 00:11:23,600 --> 00:11:24,600 Yeah, you can always tell. 154 00:11:24,600 --> 00:11:27,600 --right, the little delay, the font rendering. 155 00:11:27,600 --> 00:11:30,600 I mean, just a million things that are so obviously apparent, 156 00:11:30,600 --> 00:11:33,600 maybe not from screenshots, but the minute you start using an application. 157 00:11:33,600 --> 00:11:34,600 Yeah. 158 00:11:34,600 --> 00:11:36,600 And so that was really a hard requirement for us 159 00:11:36,600 --> 00:11:40,600 is that it needs to be actually native on both platforms. 160 00:11:40,600 --> 00:11:42,600 And I think it's the right requirement as well 161 00:11:42,600 --> 00:11:50,600 because I think it is really just very important for that platform look and feel, 162 00:11:50,600 --> 00:11:53,600 especially the feel, actually, more than the look, 163 00:11:53,600 --> 00:11:56,600 that it is using the native libraries. 164 00:11:56,600 --> 00:12:04,600 And it's an approach that Salim used with the Windows integration libraries. 165 00:12:04,600 --> 00:12:07,600 They were--when I first saw that project, 166 00:12:07,600 --> 00:12:11,600 I kind of assumed that it was going to use SwiftUI 167 00:12:11,600 --> 00:12:14,600 and then kind of mock up the SwiftUI on Windows, 168 00:12:14,600 --> 00:12:16,600 but actually it's not that at all. 169 00:12:16,600 --> 00:12:23,600 So the Swift WinRT packages hook into the native Windows APIs 170 00:12:23,600 --> 00:12:27,600 rather than trying to do cross-platform UI. 171 00:12:27,600 --> 00:12:28,600 Yeah, exactly. 172 00:12:28,600 --> 00:12:32,600 And we just feel that, you know, you look at all the best-in-class applications, 173 00:12:32,600 --> 00:12:35,600 even the ones made by Google and Facebook 174 00:12:35,600 --> 00:12:40,600 who run the Flutter and React Native projects respectively, 175 00:12:40,600 --> 00:12:42,600 they all write their applications twice, 176 00:12:42,600 --> 00:12:45,600 once in Swift and Objective-C for iOS 177 00:12:45,600 --> 00:12:48,600 and another time in Java and Kotlin for Android. 178 00:12:48,600 --> 00:12:52,600 Because of that, you just cannot get that premium feel 179 00:12:52,600 --> 00:12:56,600 if you're not using the native toolkits. 180 00:12:56,600 --> 00:12:59,600 And where, you know, Skip kind of has an easy time 181 00:12:59,600 --> 00:13:04,600 is that on the iOS side, we're just using an intermediated SwiftUI. 182 00:13:04,600 --> 00:13:08,600 Like, we don't stand in between you and, you know, real Swift 183 00:13:08,600 --> 00:13:10,600 because we're not really doing anything on iOS. 184 00:13:10,600 --> 00:13:13,600 It's on Android where we take your SwiftUI 185 00:13:13,600 --> 00:13:16,600 and we translate that into the equivalent native calls 186 00:13:16,600 --> 00:13:18,600 using what's called Jetpack Compose, 187 00:13:18,600 --> 00:13:21,600 which is kind of Android's equivalent of SwiftUI, 188 00:13:21,600 --> 00:13:24,600 and which is their recommended, you know, native toolkit 189 00:13:24,600 --> 00:13:26,600 for building Android applications. 190 00:13:26,600 --> 00:13:29,600 So we really only have half that problem to tackle, 191 00:13:29,600 --> 00:13:31,600 which doesn't mean that it's easy. 192 00:13:31,600 --> 00:13:33,600 It's actually extremely difficult in many ways. 193 00:13:33,600 --> 00:13:36,600 But it means that we only have that side of it 194 00:13:36,600 --> 00:13:39,600 to really have to, you know, nail down all the features 195 00:13:39,600 --> 00:13:40,600 and all the polish. 196 00:13:40,600 --> 00:13:44,600 Right, and that sounds like there's a bit of gluing together 197 00:13:44,600 --> 00:13:47,600 that you need to do in instrumenting the APIs, right? 198 00:13:47,600 --> 00:13:49,600 And that sort of leads me to the question, 199 00:13:49,600 --> 00:13:51,600 how ready is--are there any types of apps 200 00:13:51,600 --> 00:13:53,600 that this is particularly suited for? 201 00:13:53,600 --> 00:13:58,600 Are there any gaps you still have to sort of, you know, 202 00:13:58,600 --> 00:14:01,600 fill in, or what's the overall state 203 00:14:01,600 --> 00:14:05,600 and what kind of apps you could be targeting? 204 00:14:05,600 --> 00:14:09,600 Yeah, yeah, so we have a very large percentage 205 00:14:09,600 --> 00:14:12,600 of the SwiftUI API covered where we, you know, 206 00:14:12,600 --> 00:14:15,600 translate it into the equivalent Jetpack Compose 207 00:14:15,600 --> 00:14:17,600 and native Android UI. 208 00:14:17,600 --> 00:14:21,600 If your app can use primarily stock SwiftUI components, 209 00:14:21,600 --> 00:14:24,600 you know, things like line of business applications, 210 00:14:24,600 --> 00:14:25,600 you know, things like that, 211 00:14:25,600 --> 00:14:28,600 then you're going to have a really good experience 212 00:14:28,600 --> 00:14:30,600 because you don't really have to go off the rails. 213 00:14:30,600 --> 00:14:33,600 You can just write it as if you're writing your iOS app 214 00:14:33,600 --> 00:14:35,600 and then Swift takes, you know, 215 00:14:35,600 --> 00:14:39,600 Skip takes over and handles that for Android. 216 00:14:39,600 --> 00:14:41,600 It's when you have a lot of sort of custom components. 217 00:14:41,600 --> 00:14:43,600 If you need to drop down to, like, UIKit 218 00:14:43,600 --> 00:14:46,600 or need to use a lot of Apple-only frameworks, 219 00:14:46,600 --> 00:14:49,600 that's where you need to sort of delve into 220 00:14:49,600 --> 00:14:51,600 some of Skip's extensibility options 221 00:14:51,600 --> 00:14:53,600 for being able to implement some of that yourself. 222 00:14:53,600 --> 00:14:55,600 And that's when you need to start thinking about 223 00:14:55,600 --> 00:14:57,600 doing a little bit of your own work in Kotlin, 224 00:14:57,600 --> 00:15:02,600 which is kind of a leap in terms of the complexity 225 00:15:02,600 --> 00:15:04,600 of integrating this stuff. 226 00:15:04,600 --> 00:15:07,600 Right, and it sounds like you have escape hatches, 227 00:15:07,600 --> 00:15:09,600 so you're not lost. 228 00:15:09,600 --> 00:15:11,600 You don't have to abandon your product 229 00:15:11,600 --> 00:15:12,600 if there's stuff you can't do. 230 00:15:12,600 --> 00:15:15,600 You can still escape hatch out on the Android side 231 00:15:15,600 --> 00:15:18,600 into native Kotlin and obviously on the SwiftUI side. 232 00:15:18,600 --> 00:15:22,600 Escape hatch out into the UI and still have the same app. 233 00:15:22,600 --> 00:15:24,600 You probably just if-def it somehow. 234 00:15:24,600 --> 00:15:26,600 I guess you have a mechanism to-- 235 00:15:26,600 --> 00:15:27,600 Yeah, exactly. 236 00:15:27,600 --> 00:15:30,600 We have a series of sort of escape hatches 237 00:15:30,600 --> 00:15:35,600 that go in incremental complexity degrees, 238 00:15:35,600 --> 00:15:38,600 but the simplest one is the one that we're most proud of, 239 00:15:38,600 --> 00:15:41,600 which is you can just type, you know, #ifskip 240 00:15:41,600 --> 00:15:44,600 and just drop some Kotlin right into your Swift. 241 00:15:44,600 --> 00:15:45,600 Oh, nice, okay. 242 00:15:45,600 --> 00:15:47,600 And then, you know, else if not. 243 00:15:47,600 --> 00:15:53,600 And then the Xcode build plugin will handle taking that, 244 00:15:53,600 --> 00:15:54,600 extracting it from your Swift, 245 00:15:54,600 --> 00:15:56,600 putting it out in the Kotlin, 246 00:15:56,600 --> 00:15:57,600 and then building the bridge for you 247 00:15:57,600 --> 00:15:59,600 so that the native Swift is able to communicate 248 00:15:59,600 --> 00:16:01,600 back and forth with the custom Kotlin 249 00:16:01,600 --> 00:16:03,600 that you drop into your code. 250 00:16:03,600 --> 00:16:05,600 And then you can use that as the entry point 251 00:16:05,600 --> 00:16:09,600 to accessing the whole ecosystem of Kotlin libraries 252 00:16:09,600 --> 00:16:12,600 that exist in the Android world. 253 00:16:12,600 --> 00:16:14,600 You mentioned SwiftPM plugin there. 254 00:16:14,600 --> 00:16:17,600 Is there some machinery that is particularly useful 255 00:16:17,600 --> 00:16:20,600 from the whole compiler and SwiftPM tool chain 256 00:16:20,600 --> 00:16:22,600 that makes this possible at all 257 00:16:22,600 --> 00:16:24,600 without a lot of extra instrumentation? 258 00:16:24,600 --> 00:16:28,600 Yeah, yeah, no, the full build plugin system, 259 00:16:28,600 --> 00:16:30,600 you know, Skip wouldn't be possible without it 260 00:16:30,600 --> 00:16:32,600 because the way Skip works is, you know, 261 00:16:32,600 --> 00:16:35,600 you just work in Xcode and you develop your app 262 00:16:35,600 --> 00:16:36,600 and you build and run it 263 00:16:36,600 --> 00:16:39,600 and it launches it on the iOS simulator as normal, 264 00:16:39,600 --> 00:16:41,600 but it also launches it side by side 265 00:16:41,600 --> 00:16:42,600 on the Android emulator. 266 00:16:42,600 --> 00:16:45,600 So you can iterate on these two things side by side 267 00:16:45,600 --> 00:16:47,600 and you don't have to really-- 268 00:16:47,600 --> 00:16:48,600 you don't have to launch any other tools, 269 00:16:48,600 --> 00:16:49,600 you don't have to do anything, 270 00:16:49,600 --> 00:16:52,600 and it's the magic of the build plugin that does all this. 271 00:16:52,600 --> 00:16:55,600 You know, every time you change any of your Swift, 272 00:16:55,600 --> 00:16:57,600 the build plugin picks it up, 273 00:16:57,600 --> 00:16:59,600 it does all the necessary bridging, 274 00:16:59,600 --> 00:17:01,600 it writes out, you know, 275 00:17:01,600 --> 00:17:03,600 any additional massaging it needs 276 00:17:03,600 --> 00:17:06,600 to be able to launch the Android tool chain 277 00:17:06,600 --> 00:17:07,600 to build it natively, 278 00:17:07,600 --> 00:17:09,600 packages up your application, 279 00:17:09,600 --> 00:17:11,600 puts it on the device or the emulator 280 00:17:11,600 --> 00:17:12,600 and then runs it. 281 00:17:12,600 --> 00:17:15,600 That's really all handled by the build tool plugin. 282 00:17:15,600 --> 00:17:18,600 So without that, it really would not have been-- 283 00:17:18,600 --> 00:17:20,600 it would not have been nearly as smooth a process. 284 00:17:20,600 --> 00:17:23,600 You'd need to be having extra steps 285 00:17:23,600 --> 00:17:24,600 where you go to the command line 286 00:17:24,600 --> 00:17:26,600 and launch external tools and things like that. 287 00:17:26,600 --> 00:17:27,600 - That sounds great. 288 00:17:27,600 --> 00:17:30,600 - And coming at this from the other side, 289 00:17:30,600 --> 00:17:33,600 there is, of course, Kotlin Multiplatform. 290 00:17:33,600 --> 00:17:35,600 How do you feel about Kotlin Multiplatform? 291 00:17:35,600 --> 00:17:38,600 - Yeah, so we've worked with it actually quite a bit. 292 00:17:38,600 --> 00:17:39,600 Skip, in some modes, 293 00:17:39,600 --> 00:17:42,600 does actually integrate somewhat with Kotlin Multiplatform, 294 00:17:42,600 --> 00:17:46,600 but for the most part, you can kind of view Skip 295 00:17:46,600 --> 00:17:48,600 as the inverse of Kotlin Multiplatform 296 00:17:48,600 --> 00:17:52,600 where they have a mechanism where, you know, 297 00:17:52,600 --> 00:17:55,600 they take Kotlin and they build and, you know-- 298 00:17:55,600 --> 00:17:59,600 it's just your regular Kotlin in the Android development side, 299 00:17:59,600 --> 00:18:00,600 so it's not doing anything there, 300 00:18:00,600 --> 00:18:04,600 but when you deploy on iOS, what it does is 301 00:18:04,600 --> 00:18:08,600 it creates essentially Objective-C wrappers 302 00:18:08,600 --> 00:18:11,600 around that Kotlin, and it compiles it for iOS, 303 00:18:11,600 --> 00:18:14,600 and then you sort of have an XE framework 304 00:18:14,600 --> 00:18:16,600 that you hand off to your iOS developers, 305 00:18:16,600 --> 00:18:17,600 and you can use it to implement 306 00:18:17,600 --> 00:18:20,600 sort of the business logic of your application. 307 00:18:20,600 --> 00:18:23,600 You'll still be writing the two user interfaces separately, 308 00:18:23,600 --> 00:18:25,600 one in Android Studio and one in Xcode, 309 00:18:25,600 --> 00:18:29,600 but you'll be able to share a lot of the low-level logic. 310 00:18:29,600 --> 00:18:34,600 So in many ways, Skip is kind of the inverse of that process 311 00:18:34,600 --> 00:18:37,600 when all you're using Skip for is sharing business logic. 312 00:18:37,600 --> 00:18:42,600 But then in addition to that, you can also use Skip 313 00:18:42,600 --> 00:18:44,600 for the whole sort of vertically integrated 314 00:18:44,600 --> 00:18:46,600 user interface side as well, 315 00:18:46,600 --> 00:18:48,600 which Kotlin Multiplatform doesn't have 316 00:18:48,600 --> 00:18:50,600 quite the same experience around. 317 00:18:50,600 --> 00:18:51,600 Sure. 318 00:18:51,600 --> 00:18:54,600 I think the other thing we wanted to talk about today 319 00:18:54,600 --> 00:19:00,600 was the recent announcement and founding 320 00:19:00,600 --> 00:19:03,600 of the Swift on Android workgroup, 321 00:19:03,600 --> 00:19:07,600 which is, is it yet an official? 322 00:19:07,600 --> 00:19:09,600 I know originally it started as a community workgroup. 323 00:19:09,600 --> 00:19:12,600 Is it now an official Swift workgroup? 324 00:19:12,600 --> 00:19:14,600 Yeah, yeah, it is. 325 00:19:14,600 --> 00:19:16,600 And I should sort of rewind and say that, like, 326 00:19:16,600 --> 00:19:20,600 we at Skip did not invent this idea of Swift on Android. 327 00:19:20,600 --> 00:19:23,600 People have actually been working on it for over 10 years. 328 00:19:23,600 --> 00:19:26,600 Ever since Swift came out, people have been thinking, 329 00:19:26,600 --> 00:19:27,600 "Oh, you know, you can kind of tinker 330 00:19:27,600 --> 00:19:29,600 with the Android native development toolkits." 331 00:19:29,600 --> 00:19:33,600 You know, LLVM and things like that. 332 00:19:33,600 --> 00:19:35,600 And you can get Swift running on it. 333 00:19:35,600 --> 00:19:40,600 So it's been kind of evolving with disparate groups of people 334 00:19:40,600 --> 00:19:43,600 with different, you know, needs and levels of hobbyists 335 00:19:43,600 --> 00:19:45,600 versus professional needs. 336 00:19:45,600 --> 00:19:49,600 And it's been progressively evolving, 337 00:19:49,600 --> 00:19:52,600 but it never really came together in a cohesive whole 338 00:19:52,600 --> 00:19:56,600 where everyone was sharing ideas and implementation efforts. 339 00:19:56,600 --> 00:20:00,600 And that's something that we started back in February 340 00:20:00,600 --> 00:20:03,600 with what we called the community workgroup. 341 00:20:03,600 --> 00:20:05,600 And that was a bunch of us, 342 00:20:05,600 --> 00:20:08,600 Ioannis Andri from Reedle, 343 00:20:08,600 --> 00:20:11,600 who's been deploying Swift on Android 344 00:20:11,600 --> 00:20:14,600 with the popular Reedle Spark mail application 345 00:20:14,600 --> 00:20:16,600 for quite a long time. 346 00:20:16,600 --> 00:20:19,600 He's one of the people that really has done a lot of work 347 00:20:19,600 --> 00:20:22,600 on getting the Android SDK working. 348 00:20:22,600 --> 00:20:25,600 Ifina Golfin, who has been just devoted, you know, 349 00:20:25,600 --> 00:20:26,600 to it for a long time. 350 00:20:26,600 --> 00:20:29,600 So this sort of group has all come together and decided, 351 00:20:29,600 --> 00:20:32,600 "Okay, we're just going to, you know, pool our resources 352 00:20:32,600 --> 00:20:34,600 and we're going to focus on this." 353 00:20:34,600 --> 00:20:36,600 Oh, and of course, Salim from the browser company there, 354 00:20:36,600 --> 00:20:38,600 they're also working on this. 355 00:20:38,600 --> 00:20:40,600 And so we formed the community workgroup 356 00:20:40,600 --> 00:20:42,600 and then, you know, pretty quickly proposed 357 00:20:42,600 --> 00:20:44,600 that it be made official, 358 00:20:44,600 --> 00:20:47,600 which it was a couple of months ago in June 25th. 359 00:20:47,600 --> 00:20:50,600 So almost exactly two months ago, 360 00:20:50,600 --> 00:20:52,600 it became an official workgroup. 361 00:20:52,600 --> 00:20:55,600 And the goal there is, you know, 362 00:20:55,600 --> 00:20:57,600 the goal there is not as ambitious 363 00:20:57,600 --> 00:20:59,600 as any of our individual projects, 364 00:20:59,600 --> 00:21:01,600 which are using Swift on Android, you know, 365 00:21:01,600 --> 00:21:03,600 for our own, you know, individual needs. 366 00:21:03,600 --> 00:21:06,600 Skip, obviously, to enable people to build applications 367 00:21:06,600 --> 00:21:08,600 for both platforms, but other people just to include 368 00:21:08,600 --> 00:21:11,600 in their own individual applications. 369 00:21:11,600 --> 00:21:15,600 It's really more to get an official Android SDK 370 00:21:15,600 --> 00:21:18,600 kind of published alongside these other cross-compilation SDKs, 371 00:21:18,600 --> 00:21:21,600 like the MUSEOL and the WASM SDKs, 372 00:21:21,600 --> 00:21:25,600 and establish it as an officially supported platform 373 00:21:25,600 --> 00:21:26,600 for Android. 374 00:21:26,600 --> 00:21:27,600 That's great. 375 00:21:27,600 --> 00:21:29,600 Yeah, is there, like, in the workgroup, 376 00:21:29,600 --> 00:21:32,600 is there anything in particular you have on your sort of to-do list 377 00:21:32,600 --> 00:21:35,600 that you feel like you need to tackle? 378 00:21:35,600 --> 00:21:38,600 Any specifics there that you can share, 379 00:21:38,600 --> 00:21:40,600 that you want to share? 380 00:21:40,600 --> 00:21:43,600 Yeah, yeah. I mean, so there's a lot. 381 00:21:43,600 --> 00:21:45,600 So, you know, the first sort of deliverable 382 00:21:45,600 --> 00:21:47,600 that we're on the verge of getting out there 383 00:21:47,600 --> 00:21:51,600 is an official SDK, where you can, you know, 384 00:21:51,600 --> 00:21:54,600 just like you can cross-compile from macOS to static Linux, 385 00:21:54,600 --> 00:21:57,600 you'll be able to cross-compile to Android. 386 00:21:57,600 --> 00:21:59,600 But that's really only a single piece 387 00:21:59,600 --> 00:22:01,600 of the whole Android story, right? 388 00:22:01,600 --> 00:22:02,600 What do you get out of that? 389 00:22:02,600 --> 00:22:04,600 You can get an executable Hello World application 390 00:22:04,600 --> 00:22:07,600 that you can just, you know, run on Android, 391 00:22:07,600 --> 00:22:09,600 or you can, you know, create a shared object file, 392 00:22:09,600 --> 00:22:12,600 which you can then embed in your Android application 393 00:22:12,600 --> 00:22:14,600 and then access. 394 00:22:14,600 --> 00:22:17,600 But filling in the rest of the story 395 00:22:17,600 --> 00:22:20,600 is a pretty large, you know, sort of next step. 396 00:22:20,600 --> 00:22:22,600 For example, how do you handle resources on Android? 397 00:22:22,600 --> 00:22:26,600 You know, it's different than resources on Darwin. 398 00:22:26,600 --> 00:22:27,600 How do you handle bridging? 399 00:22:27,600 --> 00:22:30,600 You know, the reality, you know, of Android 400 00:22:30,600 --> 00:22:32,600 is that it is a Java-based platform. 401 00:22:32,600 --> 00:22:35,600 You know, almost all the APIs that you need 402 00:22:35,600 --> 00:22:37,600 to talk to the system, to the device sensors, 403 00:22:37,600 --> 00:22:40,600 you know, to Bluetooth, to GPS, 404 00:22:40,600 --> 00:22:42,600 are implemented in Java. 405 00:22:42,600 --> 00:22:45,600 So you can't just do that with C bridging. 406 00:22:45,600 --> 00:22:49,600 You need to bridge across to Java and Kotlin, 407 00:22:49,600 --> 00:22:52,600 which is, you know, a pretty complex topic, 408 00:22:52,600 --> 00:22:53,600 you know, to begin with, 409 00:22:53,600 --> 00:22:55,600 and then on top of it, doing it efficiently, 410 00:22:55,600 --> 00:22:57,600 you know, for a mobile application 411 00:22:57,600 --> 00:22:59,600 is an additional complexity. 412 00:22:59,600 --> 00:23:02,600 So we've actually been working with the Swift Java team, 413 00:23:02,600 --> 00:23:05,600 mostly Conrad, on starting to come up 414 00:23:05,600 --> 00:23:09,600 with some baseline interoperability standards 415 00:23:09,600 --> 00:23:12,600 and recommendations for how Java is going to integrate 416 00:23:12,600 --> 00:23:16,600 with Android, along with the other deployment scenarios 417 00:23:16,600 --> 00:23:17,600 for Swift Java, which is, you know, 418 00:23:17,600 --> 00:23:21,600 largely server-side integration. 419 00:23:21,600 --> 00:23:23,600 So that's a really big one. 420 00:23:23,600 --> 00:23:27,600 And then just the whole story around, you know, 421 00:23:27,600 --> 00:23:32,600 packaging, ID integration, debugging. 422 00:23:32,600 --> 00:23:35,600 There's a whole world of kind of next steps 423 00:23:35,600 --> 00:23:38,600 in order to complete the project. 424 00:23:38,600 --> 00:23:41,600 Now, we sort of at Skip have our own solutions 425 00:23:41,600 --> 00:23:42,600 for a lot of these things. 426 00:23:42,600 --> 00:23:44,600 You know, we integrate with Xcode. 427 00:23:44,600 --> 00:23:47,600 We handle bundling in our own way and things like that. 428 00:23:47,600 --> 00:23:50,600 But the more that we can get that, you know, 429 00:23:50,600 --> 00:23:53,600 worked out in a standardized way 430 00:23:53,600 --> 00:23:55,600 where everyone who's using Swift on Android 431 00:23:55,600 --> 00:23:57,600 will kind of do it in the same way, 432 00:23:57,600 --> 00:24:00,600 really only helps, you know, all of the community 433 00:24:00,600 --> 00:24:04,600 in order to have, you know, the right way to do this. 434 00:24:04,600 --> 00:24:07,600 - And how has feedback from the community 435 00:24:07,600 --> 00:24:09,600 been to the work group? 436 00:24:09,600 --> 00:24:12,600 - Great. You know, people are really excited. 437 00:24:12,600 --> 00:24:14,600 There is a lot of, you know, sort of 438 00:24:14,600 --> 00:24:17,600 what next kind of questions, because, you know, 439 00:24:17,600 --> 00:24:20,600 as I mentioned, the output of the current SDK 440 00:24:20,600 --> 00:24:24,600 is here's your shared object file, you know, 441 00:24:24,600 --> 00:24:25,600 you know, go at it. 442 00:24:25,600 --> 00:24:26,600 And then people are like, well, how am I supposed 443 00:24:26,600 --> 00:24:30,600 to talk to this from my Android app and things like that? 444 00:24:30,600 --> 00:24:32,600 But it also has, I mean, there have been 445 00:24:32,600 --> 00:24:35,600 a tremendous response to the announcement. 446 00:24:35,600 --> 00:24:38,600 It's been a lot of people have joined in the, you know, 447 00:24:38,600 --> 00:24:41,600 the work group meetings with feedback 448 00:24:41,600 --> 00:24:43,600 on what they want to use it for, 449 00:24:43,600 --> 00:24:45,600 what they are currently using it for. 450 00:24:45,600 --> 00:24:46,600 A lot of people we had never heard of 451 00:24:46,600 --> 00:24:49,600 who have been sort of using it in their applications 452 00:24:49,600 --> 00:24:51,600 in various ways have cropped up 453 00:24:51,600 --> 00:24:54,600 and had really good suggestions and contributions. 454 00:24:54,600 --> 00:24:57,600 - So your work group meetings are open to the public, are they? 455 00:24:57,600 --> 00:24:58,600 - Yep, yep. They're open. 456 00:24:58,600 --> 00:25:01,600 If you look at the, you know, Swift work group charter, 457 00:25:01,600 --> 00:25:03,600 we have the schedule there 458 00:25:03,600 --> 00:25:06,600 and people can just, you know, drop in 459 00:25:06,600 --> 00:25:09,600 and, you know, ask questions or offer contributions. 460 00:25:09,600 --> 00:25:12,600 It's been a really good process so far. 461 00:25:12,600 --> 00:25:14,600 - That's great. How often do you meet? 462 00:25:14,600 --> 00:25:15,600 - We meet every two weeks. 463 00:25:15,600 --> 00:25:19,600 - So quite a good cadence to see new stuff happening 464 00:25:19,600 --> 00:25:22,600 in the Swift on Android ecosystem. 465 00:25:22,600 --> 00:25:24,600 - Yeah, actually we have another meeting tomorrow. 466 00:25:24,600 --> 00:25:27,600 - I keep going back in my head to my earlier question 467 00:25:27,600 --> 00:25:31,600 how Swift on Android is sort of different from Linux. 468 00:25:31,600 --> 00:25:34,600 And as you talk and keep talking about then Java stuff, 469 00:25:34,600 --> 00:25:39,600 it feels like it's almost like this isn't the right, 470 00:25:39,600 --> 00:25:44,600 it's like on the Apple side, this was Swift for iOS, right? 471 00:25:44,600 --> 00:25:47,600 Because you immediately associate with Android 472 00:25:47,600 --> 00:25:49,600 and Android app is a mobile app, right? 473 00:25:49,600 --> 00:25:52,600 It's not the Linux kind binary. 474 00:25:52,600 --> 00:25:55,600 As you said, the shared object file doesn't give you anything. 475 00:25:55,600 --> 00:26:00,600 It's like if on iOS you had a, 476 00:26:00,600 --> 00:26:02,600 I mean, there is no terminal, but you know, 477 00:26:02,600 --> 00:26:04,600 like had a little binary that ran without any UI. 478 00:26:04,600 --> 00:26:08,600 That is not an app in the sense that is useful for the platform. 479 00:26:08,600 --> 00:26:13,600 So it's kind of makes it obvious what a big task it is 480 00:26:13,600 --> 00:26:18,600 to have not just the plumbing to get the code on there, 481 00:26:18,600 --> 00:26:22,600 but there's all the user facing stuff that needs to be there 482 00:26:22,600 --> 00:26:25,600 and that needs to happen. That's super interesting. 483 00:26:25,600 --> 00:26:26,600 - Yeah, yeah, definitely. 484 00:26:26,600 --> 00:26:29,600 Like, you know, sort of on Linux, you can imagine, 485 00:26:29,600 --> 00:26:32,600 I know there's a project to have bindings to GTK, 486 00:26:32,600 --> 00:26:36,600 one of the popular Linux graphical toolkits. 487 00:26:36,600 --> 00:26:40,600 And, you know, with that, you can just build an executable, 488 00:26:40,600 --> 00:26:42,600 you know, and link it to those bindings 489 00:26:42,600 --> 00:26:44,600 and then you can have an application come up on the screen. 490 00:26:44,600 --> 00:26:46,600 You know, it's all in C. 491 00:26:46,600 --> 00:26:49,600 And so you're going to be able to kind of access the world that way. 492 00:26:49,600 --> 00:26:54,600 But Android applications are sort of the mirror of iOS applications. 493 00:26:54,600 --> 00:26:56,600 They're packaged in a very specific way. 494 00:26:56,600 --> 00:26:58,600 They're launched in a very specific way. 495 00:26:58,600 --> 00:27:00,600 It's not just an executable. 496 00:27:00,600 --> 00:27:03,600 It's a whole, you know, there's resources that are bundled 497 00:27:03,600 --> 00:27:05,600 with certain conventions. 498 00:27:05,600 --> 00:27:09,600 There are, you know, derived resources like translation files 499 00:27:09,600 --> 00:27:10,600 and things like that. 500 00:27:10,600 --> 00:27:12,600 So it's really more of an application environment 501 00:27:12,600 --> 00:27:16,600 that you need to think about how you're going to integrate with. 502 00:27:16,600 --> 00:27:19,600 And that's where it really gets tricky. 503 00:27:19,600 --> 00:27:22,600 And to do it in a way where it doesn't feel like 504 00:27:22,600 --> 00:27:27,600 you're force fitting some alien technology into, you know, into Android. 505 00:27:27,600 --> 00:27:31,600 And that's why, you know, it's all done using the fairly standard, 506 00:27:31,600 --> 00:27:35,600 you know, Android native development toolkit mechanism 507 00:27:35,600 --> 00:27:39,600 that's used by any application that uses any native code, 508 00:27:39,600 --> 00:27:42,600 which is, you know, largely games, but, you know, 509 00:27:42,600 --> 00:27:46,600 many, many applications have some requirement for native code 510 00:27:46,600 --> 00:27:50,600 because it's just faster and you can avoid the, you know, 511 00:27:50,600 --> 00:27:53,600 garbage collection hangs and things like that. 512 00:27:53,600 --> 00:27:55,600 Yeah, I mean, the whole thing, it's like, despite next year 513 00:27:55,600 --> 00:27:58,600 being the year of Linux on the desktop, 514 00:27:58,600 --> 00:28:02,600 the command line is sort of a very default user interface for Linux apps. 515 00:28:02,600 --> 00:28:06,600 So having just that, which is what Swift gives you by default, 516 00:28:06,600 --> 00:28:09,600 you know, server-side Swift, that's all of it. 517 00:28:09,600 --> 00:28:12,600 That's a huge ecosystem on Linux, right? 518 00:28:12,600 --> 00:28:14,600 And, you know, the bindings you mentioned, there's not even, 519 00:28:14,600 --> 00:28:19,600 you even have to, there is no default UI binding for Linux, right? 520 00:28:19,600 --> 00:28:21,600 There's GTK, there's QT. 521 00:28:21,600 --> 00:28:25,600 I'm not sure what the sort of, in quotes, market share is for either. 522 00:28:25,600 --> 00:28:28,600 And there's more than those two. 523 00:28:28,600 --> 00:28:34,600 It's on Android as on iOS and Mac OS, the story is different, right? 524 00:28:34,600 --> 00:28:36,600 There is a default user interface that everyone thinks of 525 00:28:36,600 --> 00:28:39,600 if you talk about an app on those platforms. 526 00:28:39,600 --> 00:28:43,600 And I find it fascinating how they have different aspects there. 527 00:28:43,600 --> 00:28:45,600 Yeah, yeah, absolutely. 528 00:28:45,600 --> 00:28:48,600 And so, you know, so, you know, on Linux, 529 00:28:48,600 --> 00:28:53,600 I think Qt and GTK have more or less half and half kind of distribution, 530 00:28:53,600 --> 00:28:55,600 you know, one being the default for GNOME 531 00:28:55,600 --> 00:28:58,600 and one being the default for KDE. 532 00:28:58,600 --> 00:29:02,600 But you have the benefit of it can just be a self-contained binary. 533 00:29:02,600 --> 00:29:05,600 And as you say, command line tools are also, you know, 534 00:29:05,600 --> 00:29:09,600 probably the majority of Linux applications that you wind up running. 535 00:29:09,600 --> 00:29:13,600 And so you kind of, Swift has a very natural fit there 536 00:29:13,600 --> 00:29:16,600 because you can just sort of pull in all these packages. 537 00:29:16,600 --> 00:29:20,600 And your user interface is the Swift, you know, argument parser, really. 538 00:29:20,600 --> 00:29:21,600 Great. 539 00:29:21,600 --> 00:29:25,600 Well, we should probably move on to some package picks for the week. 540 00:29:25,600 --> 00:29:29,600 We asked Mark to bring along a couple of picks. 541 00:29:29,600 --> 00:29:35,600 And my only question is, is your first pick Android compatible? 542 00:29:35,600 --> 00:29:37,600 Yes. 543 00:29:37,600 --> 00:29:44,600 So, yeah, my first pick is it's Uncertain by Matt Thompson, 544 00:29:44,600 --> 00:29:47,600 @ttt. 545 00:29:47,600 --> 00:29:51,600 And it's a Swift implementation of an old Microsoft library, 546 00:29:51,600 --> 00:29:55,600 not old, but a Microsoft paper from around 10 years ago. 547 00:29:55,600 --> 00:29:57,600 I saw this package, yeah. 548 00:29:57,600 --> 00:29:58,600 Oh, yeah. 549 00:29:58,600 --> 00:30:03,600 So it's about sort of rigorously treating uncertainty in a data type. 550 00:30:03,600 --> 00:30:08,600 It's just uncertain, you know, generic across T. 551 00:30:08,600 --> 00:30:11,600 And it's really neat. 552 00:30:11,600 --> 00:30:15,600 It lets you, rather than, you know, in your own code, 553 00:30:15,600 --> 00:30:18,600 when you're saying, "Oh, is this GPS coordinate, like, close enough? 554 00:30:18,600 --> 00:30:20,600 Is it within or without? 555 00:30:20,600 --> 00:30:22,600 I'll just pick 10 yards or something like that," 556 00:30:22,600 --> 00:30:25,600 and then go with it and then iterate down the road, 557 00:30:25,600 --> 00:30:30,600 it allows you sort of to encode the concept of uncertainty into your data type. 558 00:30:30,600 --> 00:30:34,600 And so you can kind of treat it in a rigorous way 559 00:30:34,600 --> 00:30:38,600 and you can compose it with other uncertain variables. 560 00:30:38,600 --> 00:30:40,600 It's a really neat idea. 561 00:30:40,600 --> 00:30:42,600 Yes, it does build on Android. 562 00:30:42,600 --> 00:30:44,600 Yes, I saw it fly past. 563 00:30:44,600 --> 00:30:47,600 It was a few weeks since it's been released, I think. 564 00:30:47,600 --> 00:30:50,600 It looks like--oh, yeah, it looks like it's been in development for a month. 565 00:30:50,600 --> 00:30:54,600 So I think it was a couple of weeks since I saw it fly past, 566 00:30:54,600 --> 00:30:56,600 and it did catch my eye. 567 00:30:56,600 --> 00:31:00,600 It's kind of a--it's slightly fun, but also-- 568 00:31:00,600 --> 00:31:03,600 it's not a frivolous package, but it is a slightly fun package. 569 00:31:03,600 --> 00:31:05,600 Yeah, no, absolutely. 570 00:31:05,600 --> 00:31:09,600 And he has a great little Mac application that you can run 571 00:31:09,600 --> 00:31:11,600 that uses Swift charts 572 00:31:11,600 --> 00:31:17,600 and visualize various uncertainty algorithms 573 00:31:17,600 --> 00:31:21,600 and parameters to it, which is pretty neat. 574 00:31:21,600 --> 00:31:23,600 Oh, that's great. I hadn't seen that. 575 00:31:23,600 --> 00:31:26,600 I had seen the package, but I hadn't seen the companion. 576 00:31:26,600 --> 00:31:28,600 I need to check that out again. 577 00:31:28,600 --> 00:31:31,600 That's a great package suggestion. 578 00:31:31,600 --> 00:31:37,600 I will go next with my first package pick for this episode. 579 00:31:37,600 --> 00:31:44,600 And it's Swift Complexity by Fumiyaka Tanaka. 580 00:31:44,600 --> 00:31:51,600 And this is a brand-new tool rather than a code library 581 00:31:51,600 --> 00:31:57,600 for testing a couple of metrics against your Swift source code. 582 00:31:57,600 --> 00:32:01,600 So it tests for cyclomatic complexity in functions 583 00:32:01,600 --> 00:32:04,600 and cognitive complexity in functions, 584 00:32:04,600 --> 00:32:08,600 which if you've--I haven't seen this done for Swift before, 585 00:32:08,600 --> 00:32:09,600 although it may have been done. 586 00:32:09,600 --> 00:32:11,600 I just may not have come across it. 587 00:32:11,600 --> 00:32:14,600 But I certainly have seen it in both the JavaScript ecosystem 588 00:32:14,600 --> 00:32:17,600 and the Ruby ecosystem. 589 00:32:17,600 --> 00:32:24,600 So cyclomatic complexity is a measure of how many paths 590 00:32:24,600 --> 00:32:25,600 through a function there are. 591 00:32:25,600 --> 00:32:27,600 So if your function is lots of if statements, 592 00:32:27,600 --> 00:32:32,600 you're going to have a very high cyclomatic complexity. 593 00:32:32,600 --> 00:32:35,600 And there's also a measure here of cognitive complexity, 594 00:32:35,600 --> 00:32:38,600 which is not something I've come across before, 595 00:32:38,600 --> 00:32:40,600 but apparently it measures how difficult it is 596 00:32:40,600 --> 00:32:43,600 for humans to understand code. 597 00:32:43,600 --> 00:32:48,600 And this is a tool that will give you a representation 598 00:32:48,600 --> 00:32:54,600 of high cyclomatic and cognitive complexity 599 00:32:54,600 --> 00:32:57,600 in functions that you've written in your code. 600 00:32:57,600 --> 00:33:01,600 So you can run it as a tool against the single Swift file 601 00:33:01,600 --> 00:33:05,600 or an entire project if you would like. 602 00:33:05,600 --> 00:33:11,600 I tested this, and as is any tool that takes source code, 603 00:33:11,600 --> 00:33:14,600 I always point it at the Swift package index source. 604 00:33:14,600 --> 00:33:19,600 And I don't think it's designed for projects of that size 605 00:33:19,600 --> 00:33:24,600 because it didn't manage to process the entirety 606 00:33:24,600 --> 00:33:27,600 of the package index server source. 607 00:33:27,600 --> 00:33:30,600 It gave up after about 10 minutes. 608 00:33:30,600 --> 00:33:32,600 Also, you've got to think about how you'd actually 609 00:33:32,600 --> 00:33:35,600 use the results of this. 610 00:33:35,600 --> 00:33:38,600 You probably don't want to know about every single 611 00:33:38,600 --> 00:33:41,600 cyclomatic complexity issue all at once. 612 00:33:41,600 --> 00:33:44,600 And so one of the things that they do mention in the readme 613 00:33:44,600 --> 00:33:48,600 for the package is that you can integrate this into, 614 00:33:48,600 --> 00:33:51,600 for example, a CI testing scenario. 615 00:33:51,600 --> 00:33:56,600 So you could, for example, do a quick CI process 616 00:33:56,600 --> 00:33:59,600 that diffs the pull request, finds out what files have changed, 617 00:33:59,600 --> 00:34:01,600 and then runs it past each of those files individually 618 00:34:01,600 --> 00:34:04,600 and maybe gives that report or something like that. 619 00:34:04,600 --> 00:34:08,600 But I thought it was an interesting little package 620 00:34:08,600 --> 00:34:11,600 and one worth mentioning. 621 00:34:11,600 --> 00:34:14,600 Did it suggest just to break the package index down 622 00:34:14,600 --> 00:34:19,600 to smaller components like the Swift compiler does? 623 00:34:19,600 --> 00:34:22,600 No, I may still have the error message in my console here, actually. 624 00:34:22,600 --> 00:34:27,600 Instead, it told us we had illegal hardware instructions. 625 00:34:27,600 --> 00:34:30,600 Ooh, all right. 626 00:34:30,600 --> 00:34:31,600 Yeah, I can see. 627 00:34:31,600 --> 00:34:34,600 In the past, working with Java libraries, 628 00:34:34,600 --> 00:34:39,600 I've seen cyclomatic complexity analysis that would be used, 629 00:34:39,600 --> 00:34:42,600 like you said, in pull requests, 630 00:34:42,600 --> 00:34:45,600 and would compare the cyclomatic complexity 631 00:34:45,600 --> 00:34:48,600 before and after the pull request and then say, 632 00:34:48,600 --> 00:34:51,600 "Oh, this really increases it by this amount. 633 00:34:51,600 --> 00:34:53,600 Maybe that should be a red flag." 634 00:34:53,600 --> 00:34:56,600 And I don't know how this cognitive complexity analysis works, 635 00:34:56,600 --> 00:35:00,600 but that sounds like it'd be a really interesting additional application. 636 00:35:00,600 --> 00:35:03,600 It's like, "Your pull request just made this a lot more difficult to understand. 637 00:35:03,600 --> 00:35:07,600 Maybe you should consider simplifying it." 638 00:35:07,600 --> 00:35:09,600 Yeah, I'm not sure I'd ever see any of these. 639 00:35:09,600 --> 00:35:15,600 And certainly in Ruby code, where there's a tool called Rubocop, 640 00:35:15,600 --> 00:35:20,600 which will happily tell you about your cyclomatic complexity problems, 641 00:35:20,600 --> 00:35:24,600 it's the kind of thing that quite often you'd look at it and go, 642 00:35:24,600 --> 00:35:26,600 "Actually, I'm kind of okay with that code, 643 00:35:26,600 --> 00:35:29,600 but yes, here there was a problem that we need to fix." 644 00:35:29,600 --> 00:35:34,600 So it's not something that I'd expect to see be a blocker to merging a pull request, 645 00:35:34,600 --> 00:35:39,600 but as an indicator of maybe you've gone too far in this function. 646 00:35:39,600 --> 00:35:42,600 Right. My turn, I guess. 647 00:35:42,600 --> 00:35:43,600 It certainly is. 648 00:35:43,600 --> 00:35:49,600 And my pick is SQL Cipher by Micah Moore of Zetetic. 649 00:35:49,600 --> 00:35:52,600 Zetetic is the company behind SQL Cipher, 650 00:35:52,600 --> 00:35:56,600 and this is the official Swift package for the project. 651 00:35:56,600 --> 00:36:04,600 I first learned about SQL Cipher when I was working for a bank quite a number of years ago now. 652 00:36:04,600 --> 00:36:11,600 And what it does is it is a fork of SQLite, of the official SQLite database library, 653 00:36:11,600 --> 00:36:15,600 and adds 256-bit AES encryption of database files. 654 00:36:15,600 --> 00:36:23,600 And then it obviously is immediately obvious why banks might be interested in that in particular, 655 00:36:23,600 --> 00:36:30,600 because they have strong requirements on data security, like on-device encryption, all that sort of stuff. 656 00:36:30,600 --> 00:36:39,600 And so this is what this gives you effectively, a SQLite store that is encrypted and has the normal SQLite APIs, 657 00:36:39,600 --> 00:36:45,600 so you can use it with all your normal processes, your APIs and packages and stuff, 658 00:36:45,600 --> 00:36:51,600 and this is sort of taking care of making sure that the file at rest is encrypted. 659 00:36:51,600 --> 00:36:56,600 I'm not sure to what extent it is encrypted in memory. 660 00:36:56,600 --> 00:36:58,600 It's quite extensive. 661 00:36:58,600 --> 00:37:03,600 There's a good documentation about what they actually do, how far this goes. 662 00:37:03,600 --> 00:37:07,600 Obviously, you need to consider how you handle your passphrases, 663 00:37:07,600 --> 00:37:13,600 because if you have a binary that encrypts the file, but then you have the passphrase sort of in your binary, 664 00:37:13,600 --> 00:37:15,600 that's not super secure, right? 665 00:37:15,600 --> 00:37:22,600 That is, I think we talked about this in the past with a package recommendation to deal with secrets in your code. 666 00:37:22,600 --> 00:37:28,600 But, you know, it is certainly better than just leaving the file unencrypted entirely. 667 00:37:28,600 --> 00:37:36,600 So if you have those needs, that's a great package to look at to deal with that. 668 00:37:36,600 --> 00:37:44,600 And it's probably one of the standard mechanisms actually to deal with encrypted database files on iOS devices. 669 00:37:44,600 --> 00:37:45,600 Interesting. 670 00:37:45,600 --> 00:37:53,600 And bonus, according to our compatibility matrix, it is compatible on all of them. 671 00:37:53,600 --> 00:37:57,600 So that includes the Apple platforms, Linux, Wasm, and Android. 672 00:37:57,600 --> 00:37:59,600 There we go. 673 00:37:59,600 --> 00:38:02,600 So I've actually worked with them a little bit on this, 674 00:38:02,600 --> 00:38:07,600 and it's not actually compatible with anything but Darwin platforms right now, 675 00:38:07,600 --> 00:38:15,600 because they're shipping binary XC frameworks, which I think is not triggering it to fail. 676 00:38:15,600 --> 00:38:19,600 It was somewhat urgent for them to get something out the door, 677 00:38:19,600 --> 00:38:23,600 because previously they had been distributing things via CocoaPods, 678 00:38:23,600 --> 00:38:31,600 and with CocoaPods sort of imminent, CocoaPods is really winding down. 679 00:38:31,600 --> 00:38:38,600 They needed some other way to ship SQL Cipher support for Darwin platforms. 680 00:38:38,600 --> 00:38:45,600 But I am working with them actually on getting Android support via ideally having a source build. 681 00:38:45,600 --> 00:38:52,600 I've been working actually on this for a while, both with them and with Gwendolyn Roof with the GRDB project, 682 00:38:52,600 --> 00:38:59,600 whose SQL Cipher integration also relies on the older CocoaPods binary integration. 683 00:38:59,600 --> 00:39:04,600 So hopefully we will have a better cross-platform story with that right now, 684 00:39:04,600 --> 00:39:09,600 because it really is a de facto sort of gold standard for SQLite encryption support. 685 00:39:09,600 --> 00:39:16,600 Applications like Signal use it to keep their local database of chats encrypted and things like that. 686 00:39:16,600 --> 00:39:20,600 Yeah, I just realized now that you say that. 687 00:39:20,600 --> 00:39:25,600 We do indicate that a package includes binary-only targets, 688 00:39:25,600 --> 00:39:38,600 and I suppose our compatibility check fails in the sense that all it does is fetch the binary target 689 00:39:38,600 --> 00:39:40,600 and then does nothing with it, I suppose. 690 00:39:40,600 --> 00:39:47,600 I just checked. We have no error messages, but yeah, that's a gap definitely that we have there in our checking. 691 00:39:47,600 --> 00:39:48,600 There you go. 692 00:39:48,600 --> 00:39:58,600 Yeah, fortunately on the horizon, we will potentially have support for binary frameworks for non-Darwin platforms 693 00:39:58,600 --> 00:40:03,600 in the not-too-distant future as static archives, right? 694 00:40:03,600 --> 00:40:08,600 Because there is no ABI stability for non-Darwin platforms yet. 695 00:40:08,600 --> 00:40:12,600 But even a static archive for a package like this would be sufficient. 696 00:40:12,600 --> 00:40:17,600 Even if they will only ship a binary distribution, 697 00:40:17,600 --> 00:40:23,600 there is a potential for compatibility with multiple platforms in the not-too-distant future. 698 00:40:23,600 --> 00:40:29,600 Fantastic. Do you want to give us one last package recommendation or pick, Mark? 699 00:40:29,600 --> 00:40:34,600 Yeah, I'm going to go with Lottie by Airbnb. 700 00:40:34,600 --> 00:40:43,600 That's a framework for rendering vector animations that have been exported from Adobe After Effects, 701 00:40:43,600 --> 00:40:49,600 which is kind of the industry standard for creating really fancy vector animations. 702 00:40:49,600 --> 00:40:53,600 And Lottie is a fantastic application, super efficient. 703 00:40:53,600 --> 00:40:57,600 If you ever see really cutesy kind of animation-driven applications, 704 00:40:57,600 --> 00:41:00,600 one of the notable ones being Duolingo, 705 00:41:00,600 --> 00:41:05,600 those are almost exclusively driven using Lottie exported animations. 706 00:41:05,600 --> 00:41:10,600 They're very compact, they're vector-based, so they're always sharp on whatever screen. 707 00:41:10,600 --> 00:41:14,600 They're never blurry and things like that. 708 00:41:14,600 --> 00:41:21,600 And most importantly, you don't have to worry about the creation tool because there are... 709 00:41:21,600 --> 00:41:26,600 I mean, the most famous one is After Effects to create the animations, 710 00:41:26,600 --> 00:41:30,600 but the format that it goes into, I think it's... 711 00:41:30,600 --> 00:41:32,600 What's the intermediate format? 712 00:41:32,600 --> 00:41:36,600 It's adjacent. They call it Body Move-In, the expert plugin, I think. 713 00:41:36,600 --> 00:41:38,600 That's it, yeah. 714 00:41:38,600 --> 00:41:43,600 And so the biggest part of creating animations like that is how do you actually create them? 715 00:41:43,600 --> 00:41:46,600 And so it completely sidesteps that, letting other people do it, 716 00:41:46,600 --> 00:41:49,600 which I really like about this package and this technique. 717 00:41:49,600 --> 00:41:52,600 Yeah, yeah, yeah. It's a great package. 718 00:41:52,600 --> 00:41:57,600 And you asked if the other one I mentioned built on Android. 719 00:41:57,600 --> 00:42:04,600 This actually does not build on Android because it uses... 720 00:42:04,600 --> 00:42:09,600 Sorry, my brain is... 721 00:42:09,600 --> 00:42:12,600 Core Animation for its implementation of animation, 722 00:42:12,600 --> 00:42:14,600 which of course is an Apple-only framework. 723 00:42:14,600 --> 00:42:17,600 But there is a Kotlin side to it, it's Lottie Kotlin, 724 00:42:17,600 --> 00:42:24,600 that implements them using Android's canvas vector rendering animation. 725 00:42:24,600 --> 00:42:27,600 And that's actually one of the popular packages for Skip, 726 00:42:27,600 --> 00:42:30,600 is one that bridges between these two so that you can... 727 00:42:30,600 --> 00:42:35,600 With your Skip application, you can ship a Lottie animation, 728 00:42:35,600 --> 00:42:39,600 and on iOS, it will use the Lottie iOS Core Animation package, 729 00:42:39,600 --> 00:42:43,600 and on Android, it will use their equivalent Kotlin implementation. 730 00:42:45,600 --> 00:42:47,600 Well, that's great. I have a feeling... 731 00:42:47,600 --> 00:42:52,600 I didn't stop you because I wasn't 100% sure, 732 00:42:52,600 --> 00:42:56,600 but I have a feeling we have had Lottie on the podcast before. 733 00:42:56,600 --> 00:43:00,600 Oh, okay. I did go through the past 20 or 30 and I didn't see it. 734 00:43:00,600 --> 00:43:01,600 It was ages ago. 735 00:43:01,600 --> 00:43:02,600 But I didn't exhaustively go through them all. 736 00:43:02,600 --> 00:43:05,600 Well, there are some that have been lost to time. 737 00:43:05,600 --> 00:43:08,600 Yeah, we started this as Twitter Spaces, 738 00:43:08,600 --> 00:43:10,600 back when Twitter Spaces were a thing. 739 00:43:10,600 --> 00:43:15,600 And so I think we managed to capture some of the recordings from those, 740 00:43:15,600 --> 00:43:17,600 but certainly not all of them. 741 00:43:17,600 --> 00:43:20,600 So you are absolutely forgiven. 742 00:43:20,600 --> 00:43:22,600 Plus, this is episode 61, 743 00:43:22,600 --> 00:43:26,600 and so I think it's high time that we highlighted Lottie again. 744 00:43:26,600 --> 00:43:29,600 Real-time follow-up. It was in episode 17, 745 00:43:29,600 --> 00:43:32,600 so that is in the distant past. 746 00:43:32,600 --> 00:43:34,600 It is well worth a re-mention. 747 00:43:34,600 --> 00:43:35,600 Sure. Yeah. 748 00:43:37,600 --> 00:43:40,600 Well, and with that, we shall call it another episode. 749 00:43:40,600 --> 00:43:45,600 So I'd like to thank Mark so much for your time 750 00:43:45,600 --> 00:43:49,600 coming on and talking about the Android Workgroup and Skip Tools. 751 00:43:49,600 --> 00:43:55,600 And we will be back in a few weeks with more Package Picks 752 00:43:55,600 --> 00:43:58,600 and some news from Package Index, I guess. 753 00:43:58,600 --> 00:43:59,600 Thanks for having me. 754 00:43:59,600 --> 00:44:03,600 Thanks, Mark, and see you in two weeks or next time, rather. 755 00:44:03,600 --> 00:44:04,600 Bye-bye. 756 00:44:04,600 --> 00:44:05,600 Thank you. Bye-bye.

Never lose your place, on any device

Create a free account to sync, back up, and get personal recommendations.