00:00:00 ◼ ► Welcome to Under the Radar, a show about independent iOS app development. I'm Marco Arment.
00:00:05 ◼ ► And I'm David Smith. Under the Radar is usually not longer than 30 minutes, so let's get started.
00:00:09 ◼ ► So the last few episodes we've been doing this series of the tools that we use to make our apps.
00:00:14 ◼ ► And I'm loving this because it's mostly Dave telling us the tools he uses and me saying, "Whoa, I never heard of that. That looks really cool."
00:00:22 ◼ ► And then going and buying them all because I use a fairly minimal set of tools, not out of choice mostly, but more out of just ignorance of what's out there.
00:00:41 ◼ ► I think this used to mean basically Google and Stack Overflow and Apple's documentation.
00:00:47 ◼ ► But in recent years with the rise of LLMs and tools built around them for coding, I think this has a lot broader of a meaning now.
00:00:55 ◼ ► So I'm really curious to see kind of how, Dave, how you're using these things and kind of where we stand with using various assistive tools for code writing.
00:01:07 ◼ ► Yeah, because I think in the day to day of what we do in our job, it's like functionally we're just trying to sit down in front of Xcode and write code that works, that solves a problem, that has a particular feature in mind.
00:01:22 ◼ ► Like the exact means and process of that will vary based on, I suppose, our familiarity with the subject matter that we're trying to deal with, the degree to which we've solved this problem before many times.
00:01:39 ◼ ► You know, if you're just trying to put together a UI and Swift UI, there's only so much assistance that you might need to do that because it's a different kind of visual problem versus if you're, say, trying to do something more of a utility fashion or you're doing a conversion or you're running some kind of more sophisticated algorithm against some data that you have.
00:02:00 ◼ ► You may need help in terms of understanding what that algorithm does or how to implement it or what some solutions for that might be.
00:02:08 ◼ ► And so depending on where you are on that broad spectrum is going to dramatically impact the degree to which you need assistance for it.
00:02:15 ◼ ► There are some operations and some things that I've done now so many times as a developer that I can just do them straightforwardly.
00:02:22 ◼ ► I don't need any help. In some ways, help would be counterproductive rather than productive for me.
00:02:30 ◼ ► And I think the main place that we all should start probably, or at least that I start when I'm developing something, is making sure that I have a good understanding of the Apple-provided tools that are available to me.
00:02:42 ◼ ► And so this is usually my first port of call is the Xcode documentation or the header files related to that, depending on exactly where it is.
00:02:51 ◼ ► Very often, generally speaking, the documentation and the header files are similar, but weirdly sometimes I find that the header files for me are more helpful.
00:03:01 ◼ ► And especially in the way that some of the stuff in Swift works, where if you go into a header file for a Swift module, it'll include huge numbers of the functions related to whatever it is you're using.
00:03:13 ◼ ► So if you go to the SwiftUI headers, it's this massive file that includes essentially all of SwiftUI.
00:03:19 ◼ ► So you can Cmd+F in there and search for various things and try and find your way around in a way that the documentation browser sometimes I find is not as helpful for that.
00:03:28 ◼ ► But broadly, it's trying to understand if the system provides a tool that I need or is trying to already solves a problem that I already have.
00:03:40 ◼ ► In fact, generally speaking, it's a bad idea to re-implement your own version of something that is provided in Foundation, is provided by UIKit or SwiftUI, or one of these very fundamental frameworks, which generally do a very good job and very, broadly speaking, are very reliable, have solved this problem in a way that is very thoughtfully done, is well tested internally and all kinds of things.
00:04:02 ◼ ► And so generally, if you can find the solution there, then that's a great place to go. And I just use Xcode directly for my documentation browsing.
00:04:10 ◼ ► I know there's a variety of tools. I think Dash is one that comes to mind that I think a lot of people found useful.
00:04:18 ◼ ► Sometimes I'll end up on the developer portal, like developer.apple.com version of the documentation.
00:04:24 ◼ ► If I'm doing a Google search or something like that for something and it ends me, I very often will find--if ultimately I'm finding a reference to the documentation, it's just good to start there and read what's available before we start getting into the more complicated parts of doing things that are pushing beyond what's just the system provided to the feature set.
00:04:45 ◼ ► It's interesting that you mentioned trying to see if the system has already written a function that you need or has already provided a solution to what you need.
00:04:54 ◼ ► Because this is an area that I feel like I'm not amazing at, and I think the era of Swift and SwiftUI has actually made that harder for me.
00:05:04 ◼ ► Because the names now are so generic and short. We don't have letter prefixes on object types anymore. You barely even have prefixes for things in certain frameworks.
00:05:17 ◼ ► It isn't just dropping the NS from all the foundation types. The store kit used to have "SK product" and now it's just "product." Stuff like that.
00:05:28 ◼ ► We're losing a lot of this name-cruff that we've had over time, but what that name-cruff did was make it really easy to search for that stuff.
00:05:41 ◼ ► There's lots of technical reasons why the way that we're doing things now is superior or nicer, but I think there's one big reason where it falls down.
00:05:54 ◼ ► So it's hard to find, for instance, "Is there a function that does this?" I don't know.
00:05:59 ◼ ► And I have also found, for whatever it's worth, that Apple's built-in documentation viewer is not as reliable or as full-featured as I would want it to be.
00:06:10 ◼ ► That's why I have historically been a Dash user, although I kind of fell out of it recently.
00:06:15 ◼ ► I have a thing about dipping back in, because I often find that when I go to search for documentation, it's not built, or the search just takes a very long time before it goes,
00:06:26 ◼ ► and so I don't know if I have zero results or if it's just indexing and it's going to pop up in a second.
00:06:30 ◼ ► I find it often difficult when I reach a leaf node in the document viewer, how do I get to the containing object or function or framework?
00:06:40 ◼ ► Some of those things are harder than they need to be or are clumsy or are not always available.
00:06:56 ◼ ► Oftentimes, I will write a function to do something like whatever it is, like chunk a string into whatever it is.
00:07:03 ◼ ► I'll write a function, and then I'll find, "Oh, there actually already was one of these."
00:07:12 ◼ ► Well, I'm never going to find that, because it's going to conflict with the 19,000 other map functions that are out there.
00:07:20 ◼ ► And the documentation viewer, for whatever reason, doesn't turn it up in a search or whatever.
00:07:24 ◼ ► So I do find the Xcode documentation to be, the viewer itself, not to mention the content of it,
00:07:36 ◼ ► It was in a much worse place a few years ago, where there were so many functions and variables and things,
00:07:52 ◼ ► and you just kind of have to guess, or you have to go to Stack Overflow or other tools.
00:08:01 ◼ ► Yeah, and I think what's interesting about that too is it's this funny hierarchy I feel like I have of,
00:08:15 ◼ ► And in some ways the top results you get from that search kind of give you a sense of how out on a limb you are,
00:08:22 ◼ ► that if the first hit to your search is something on developer.apple.com and it's a documentation page,
00:08:44 ◼ ► And sometimes the answer is there is no answer, in which case you just have to continue your search.
00:08:48 ◼ ► But it's useful if you search for something specific and that exact question was asked on Stack Overflow,
00:09:00 ◼ ► You're going to have to work this out yourself. You're going to have to go on an adventure.
00:09:04 ◼ ► And then I think that is a useful thing, or you find, you know, there's certain articles or pages that I will find
00:09:10 ◼ ► that, you know, there's some websites out there that if I see them in the top few links on Google search
00:09:17 ◼ ► for a particular topic or problem I'm trying to solve, I'm always so relieved because they've just sort of built up in time in my mind
00:09:24 ◼ ► that if they've written an article about it, then it's probably going to have the answer.
00:09:28 ◼ ► And it's going to be written in a good way. It's going to have the right information. It's not going to lead me astray.
00:09:36 ◼ ► But, you know, broadly, this is the case where you're trying to work out if a problem was solved by someone else.
00:09:43 ◼ ► And I suppose the other category of things is where you're trying to get into, okay, it's not in the documentation.
00:09:52 ◼ ► And certainly this is, I'm not saying this isn't necessarily the best way to do development.
00:09:57 ◼ ► It's a very pragmatic way, right? It's the sense of, I think so much of our development is about, you know, find easy ways to solve the easy problems.
00:10:09 ◼ ► That if you're solving something that's been solved a hundred times, you don't need to solve it yourself.
00:10:15 ◼ ► Unless that is something that you're doing for your own edification because you enjoy it, sure.
00:10:19 ◼ ► But if it's something that exists, if it's something that exists in some way otherwise, or you're just sort of teaching yourself, then that way, that's great.
00:10:27 ◼ ► But if you're not, then you're going to enter the place that you're going to have to write, you know, some whole cloth new code.
00:10:33 ◼ ► Which, you know, is probably, I don't know, it certainly varies over time, but it's probably the like 30, 40% of what I do in my job is doing that kind of work.
00:10:42 ◼ ► You know, the majority of it is probably UI work, and then there's the kind of boring boilerplate stuff, which you could very easily be getting from a Stack Overflow answer or just using system frameworks for.
00:10:55 ◼ ► And I think the more interesting thing that I've been encountering now is like you were saying, is these kind of more generative things.
00:11:01 ◼ ► So Xcode sort of has its, what is it, predictive code completion, I think is what they call it, which is their version of it.
00:11:22 ◼ ► And largely, I think it's in a weird way, so far, the only one that I use on a regular basis is weirdly the Xcode one.
00:11:33 ◼ ► And I'm going to explain why that's the case, but I think it's the thing that I find really insidious about a lot of these tools,
00:11:41 ◼ ► that if you go to ChatGPT and ask it to solve your problem, it will give you a solution.
00:11:47 ◼ ► And sometimes it will give you a very robust solution that is this like it's giving you this whole class with a variety of methods, and it can do a lot of work.
00:11:55 ◼ ► And that's great, except that is most likely that code is only 90% of the solution that you want.
00:12:02 ◼ ► That it is close enough to sort of work to pass your kind of first initial smoke testing, like is this actually kind of sort of what I want?
00:12:12 ◼ ► But then it doesn't give you the whole solution most of the time, at least in my experience.
00:12:16 ◼ ► That if it was a solution that I could, that kind of thing could give me the whole solution for, I probably wouldn't need ChatGPT.
00:12:24 ◼ ► But like if it's a hard enough problem that it doesn't have a straightforward solution, ChatGPT is only going to get me halfway there, or part of the way there.
00:12:37 ◼ ► I don't know which 10% of this code is eventually going to explode and fire and go terribly wrong.
00:12:43 ◼ ► And so for me, I haven't found those tools very reliable or something that I want to use in a way that I still have the Xcode predictive code completion turned on.
00:12:58 ◼ ► It's almost essentially, I'm using it as a slightly smarter version of code completion, where it is saving me typing, not giving me the solution, if that makes any sense as a difference.
00:13:12 ◼ ► It's very often able to see where I am and predict accurately the code I have in my head that I'm in the process of typing out.
00:13:21 ◼ ► And so it's just an accelerant to my own thinking, rather than trying to replace my thinking with something else.
00:13:30 ◼ ► It's almost like if you're in an academic situation, suppose you're working in a lab and you've got a TA helping you out.
00:13:38 ◼ ► If you ask the TA a question, they could just give you all of the solution to do your homework.
00:13:45 ◼ ► Or they could give you a little bit of a hint to get you on the right path to do it yourself.
00:13:54 ◼ ► And it kind of ruins the point, and later on that might become a problem for you because you don't actually know the solution you were handed.
00:14:01 ◼ ► Whereas if you are just being saved banging your head against the wall for a little while, or as you said, if it's literally just saving you typing, that I think is a very different kind of tool that is probably less likely to cause problems for you down the road.
00:14:20 ◼ ► And I very much appreciate that I think some of these more fancy tools can be useful if you are learning something new, because you don't know what the next line of code should be.
00:14:35 ◼ ► But I would certainly be wary if you find yourself in a place that most of what you're doing is trying to orchestrate another tool to do your thinking for you, that you're not in a particularly secure place professionally, that you're not doing a job that is nuanced and sort of creative.
00:14:55 ◼ ► And honestly, while not even necessarily from a like job security perspective, which may be complicated, but even just from an academic enrichment and fulfilling this of your job perspective, like that seems fairly shallow.
00:15:09 ◼ ► And so something that I would just be be wary of that I think these tools have found useful, you know, I do there are some places where I have been, you know, found it useful.
00:15:18 ◼ ► And sometimes what I find is using them as a more advanced search for what we're sort of we're talking about earlier for documentation.
00:15:26 ◼ ► And is there what is a, you know, I can ask it, what are what is some way that you could solve this problem, and then look at its code, and get a suggestion of like, huh, okay, that's an approach to this, or I wasn't aware of that method, or those kinds of things.
00:15:41 ◼ ► Because functionally, what a lot of these things are doing is they're trying to compress all of the, you know, accessible on the web, code in the world, and then they're trying to sort of compress it down, they're not necessarily thinking through in a creative way, but they're sort of a compression algorithm that says, if you're trying to do this, this is the code that you might end up with.
00:16:00 ◼ ► And so that can be useful. But it's also then like, you can be compressing bugs and wrong solutions, or someone who published a thing that says, Hey, I wrote this method, and it doesn't work.
00:16:12 ◼ ► But it may not have the context to realize when it's you know, in its massive data set, that this is an example of how not to write this code. And so maybe or, you know, there's lots of kind of problems that are easy to get caught up on that a lot of these these tools would won't be able to solve.
00:16:29 ◼ ► And so I think it's more just maybe that's just a cautionary tale. Maybe I'm an old man shouting at the cloud. But I think it's be careful of using these tools, whole cloth, use them as accelerants to your own thinking or ways to teach you something yourself.
00:16:41 ◼ ► But don't get too caught up into like, wow, this can just do everything because it will always give you an answer. But it will not always give you the correct answer or the most correct answer or a useful answer.
00:16:51 ◼ ► And the old joke is, you know, be careful writing code that's more than half as smart as your ability, because debugging code is twice as hard as writing code.
00:17:01 ◼ ► And so if you write code that's more than half your ability, you're going to have trouble when you then go to debug it. So this is even more of this problem if you don't even write the code, because who knows what level it's being written at?
00:17:11 ◼ ► Right. And that's, see, to me, like, I, the way I view, you know, just to get back to the question, so I also only use the built-in Xcode AI model. I don't, I've never used any of the other tools, not necessarily out of any kind of judgment, more just because I'm fairly conservative with my tools.
00:17:28 ◼ ► And by the time we finish speaking this sentence, the list of these tools that are out there is going to be different, and everything we say will be out of date anyway, because it's a very fast-moving market, as most things about LLMs are these days.
00:17:42 ◼ ► So I just don't change my tools that quickly, and I kind of don't, I don't make a habit of like messing around with new tools, because frankly, I typically don't have time to do that.
00:17:52 ◼ ► My time is better spent normally, like, just using the tools that are out there and that are established, and I kind of wait for all the, you know, early bugs to be ironed out and early problems.
00:18:02 ◼ ► Kind of wait for Apple to give me a nice version of it. But anyway, part of, you know, part of my reluctance to use things that generate more code for me, you know, it's one thing when the model is doing what the Xcode model does, which is basically, you know,
00:18:18 ◼ ► autocomplete for, you know, the line you're already on, or maybe up to a few lines long of a function, or, you know, it'll do like, if you write, you know, map, it'll write like a little basic map function of what you might have meant by the variable that you typed before it.
00:18:34 ◼ ► And it does, as far as I can tell, I think it does use your own app's code in the context window of the predictive model, and so it will have some idea of like the terminology and the structure of your app in its suggestions.
00:18:51 ◼ ► So I have found it to be a very, very good autocomplete, but again, I'm talking about something that's in the context of, you know, one to four lines of what it's generating for me, and usually just the line I'm currently on, like being a little bit completed faster.
00:19:06 ◼ ► And I find it very useful for things like, you know, filling out, you know, enum cases and switch cases for enums, because it's like, it'll figure out something like if I have, you know, an enum called download state, and the first one is downloaded, like, it'll suggest for the second one,
00:19:20 ◼ ► not downloaded, or, you know, things like that, because that is probably what I mean by that.
00:19:24 ◼ ► So from that kind of point of view, like I do find a lot of little value in, as you said, Dave, saving me typing.
00:19:31 ◼ ► But that's different from saving me from writing software, because in the end of the day, whatever code is, you know, ending up in my app, I'm responsible for it.
00:19:42 ◼ ► And I'm gonna be responsible for maintaining it over time, I'm gonna be responsible for any bugs that are in it that I'm gonna have to find and fix, and deal with the fallout of.
00:19:51 ◼ ► And so, if I, you know, one of my kind of strengths, and to many people, failings as a developer, is I don't use a lot of third-party libraries in my apps.
00:20:01 ◼ ► I use almost none, and I will usually write things myself in a minimal way, as opposed to bring in some library to do something, if it's something I can do in a reasonably small way, because I like small code.
00:20:13 ◼ ► Like, it's easier for me to keep in my head, it's easier for me to know what's going on, I have been burned a lot of times by other people's code in the past, so maybe that's just, you know, me overcorrecting for that.
00:20:23 ◼ ► But anyway, when you are using somebody else's library, you're bringing in something that someone else wrote, you inherit its strengths, you inherit its problems, it saved you time, but it might cost you time down the road, because you don't know what you just imported.
00:20:39 ◼ ► You don't know all the code in it, you didn't write it, you don't know how all of it works necessarily, even if it's open source, like, you still don't really have it in your head, and so that might cause a problem for you later.
00:20:49 ◼ ► But at least someone wrote it, and someone tested it, and someone else might be using it.
00:20:55 ◼ ► When you use LLMs to generate large amounts of code, you're basically generating a library that someone else wrote that no one has ever tested, that no one else is using, except you.
00:21:05 ◼ ► And so I feel like you're getting, like, a pretty large amount of risk for that, without getting the benefit of, like, you know, if you're bringing in something that's tricky to write, like a database.
00:21:16 ◼ ► Like, I didn't write SQLite, like, you know, I brought that in. Writing a database is hard.
00:21:21 ◼ ► If you bring in someone else's library for that, you're at least saving yourself that, but you know this is tested like crazy.
00:21:27 ◼ ► If you're bringing in, if you're, you know, having ChatGPT generate you a database, you don't have the luxury of other people testing and debugging that for you, that's all going to be on you.
00:21:37 ◼ ► So, when you, and of course, like, when you consider that example, it sounds ridiculous, like, why would I have it generate me an entire database?
00:21:42 ◼ ► Well, there's a spectrum here. So, you know, the larger the amount of code that you're having an LLM-based tool generate for you, the more risk you're taking on, and I think the less likely it is it's going to pay off for you very well in the long run.
00:21:58 ◼ ► So, there is kind of a limit on how I want to use these in terms of how much code is it generating for me at once, and I like the limit of, like, you know, one to a few lines, because that's much closer to the saving me typing end of things,
00:22:16 ◼ ► and that's something that I can look at and I can see right there if there's going to be, like, you know, something that the generated code is doing wrong, some bug it introduces,
00:22:24 ◼ ► I'm much more likely to see it if it just generated me two lines than if it generated me a whole, you know, 200 line framework.
00:22:31 ◼ ► We are brought to you this episode by Sentry. Sentry are the people who help you avoid your mobile app being the one that gets deleted next.
00:22:39 ◼ ► From getting deep context into crashes to seeing full insights and performance issues, Sentry is here to make sure your code doesn't suck.
00:22:46 ◼ ► You can fix what's broken faster and keep your app running smoothly with application monitoring built for mobile developers like us.
00:22:54 ◼ ► This is such a great tool because, you know, if you have problems with your app breaking or stalling, you have high latency, maybe you have people, like, rage clicking and tapping a bunch of buttons, you know, like, real fast, this can be really hard to debug,
00:23:06 ◼ ► it can be really hard to see without, you know, some kind of insight, so it's important to have tools like Sentry to give you insights into apps that you build.
00:23:13 ◼ ► So keep your mobile users happy. And the great news is Sentry is totally free to use. There's no reason not to check it out.
00:23:21 ◼ ► And even better, as an Under the Radar listener, you can get six months of the team plan for free.
00:23:37 ◼ ► So sentry.io/4/mobile or, again, link in the show notes, then use the code RADAR to get six months of the team plan for free.
00:23:49 ◼ ► But there are some places where I do find these sort of LLM-based tools to still be very helpful.
00:23:56 ◼ ► So, like, in the framework that we've been talking about, that I sort of, like, use them when they save you typing, not thinking,
00:24:01 ◼ ► there are places where there are things that I do that aren't thinking, but I require repetition or where they're very good.
00:24:08 ◼ ► And the one that mainly comes to mind for me is localization, which is actually something that LLMs are very good at.
00:24:19 ◼ ► That's very, it's an operation that they're surprisingly good at, I've found, and is something that I find very cumbersome and awkward to do.
00:24:28 ◼ ► And so it is something that, and what's particularly helpful, is that you can ask a tool like ChatGPT to generate output in the form of something.
00:24:38 ◼ ► And so, for example, you can write a query that says, "Can you translate this sentence, you know, give it a quoted sentence,
00:24:45 ◼ ► and return the result in the form of a, you know, an Xcode Swift strings file using the exact name as the string and, you know, prepending all of them with a comment with the language that it's translated into."
00:25:04 ◼ ► And that's something that I have found super helpful more recently, where a lot of, there's certain kinds of localization where I will actually have a native speaker actually go and do it,
00:25:17 ◼ ► But I think the practical reality I've found is that more often than not I won't, because it just isn't worth it.
00:25:23 ◼ ► It is inconvenient from a timing perspective, it requires lots of moving parts in a way that I just, you know,
00:25:29 ◼ ► and I don't want to feel like I can't add a feature or add a bit of copy into my app without, you know,
00:25:35 ◼ ► and then it adds a week and a half, two weeks to the process while I have sent the strings off to people or translators or companies or whatever.
00:25:43 ◼ ► And so very often, previously I would just use something like Google Translate and run the, makes the translations manually for all the languages that I use and then import them in.
00:25:52 ◼ ► And something like ChatGPT just automates that process for you in a way that is very helpful and is useful because you can provide a little bit of context to it as well.
00:26:03 ◼ ► In this feature it is, you know, the relevant context is that this is a workout app where someone is tracking their runs and this is the string that says "Stop workout."
00:26:16 ◼ ► And I found when I do spot checks with these and I take them and run them into various other translation services, the answers are pretty good.
00:26:23 ◼ ► And in that case, you know, in this case, it's not saving me thinking, it's not saving me typing, it's just saving me time.
00:26:36 ◼ ► And in this case I can verify it in terms of I can take the strings that have come back in these different languages and put them through other translators and see if the result is reasonable, is appropriate.
00:26:48 ◼ ► Is it, you know, sometimes it'll tell you the addition or sort of the meaning, broader, the broader meaning of that string and sort of, you know, see if it's relevant.
00:27:01 ◼ ► And I think it's funny in some ways because I think in some ways code completion is most helpful for people who aren't actually programmers.
00:27:09 ◼ ► That I hear something like ChatGPT is super helpful if you're not actually a programmer but you're trying to solve some kind of programming related task.
00:27:18 ◼ ► Because if the resulting code is only 80%, 90% good, that's probably good enough for your use case.
00:27:25 ◼ ► If you're just writing, you know, can you write me a Python script that sorts these files and does, you know, organizes them in a certain way or parses the, you know, takes this data from a spreadsheet and puts it into another form.
00:27:39 ◼ ► And the reason we're saying it's challenging as a programmer is because my job is being a programmer.
00:27:44 ◼ ► My job is writing really good quality reliable code that will stand the test of time and be able to be used by millions of users and, you know, relying on something that's automated that process is taking my special ability out of that.
00:27:57 ◼ ► It's saving the, my ability to think about programming is the thing that makes me a good programmer.
00:28:04 ◼ ► Whereas in this case, it's like what I'm saying is like rather than outsourcing any of those parts which I think are much better left in our own minds, doing things like this where localization or any kind of data processing or moving around is much more a place where I find these tools to be useful and they are useful and I think it's very much one of these situations where we just need to be applying them in the right to the right degree in the right context that don't you know use them in places that will help you do your job better, not replace your you doing your job.
00:28:33 ◼ ► And then I think you'll probably be in a good place and that's where I've been and I, you know, I use them regularly but I don't use them often. Maybe it's a good way to say that.
00:28:42 ◼ ► Yeah, I mean I use them very often in the context of like you know Xcode's autocomplete and I think yeah, you know, like any new technology, LLMs go through like you know the big boom cycle where we try to use them for everything.
00:28:55 ◼ ► And so we are kind of figuring out like okay, it's not the tool that could solve every single problem out there, but let's see where we can find value and I think we're still near obviously very early days of that, but we have found a lot of value already and there's more to find, but they shouldn't probably write your entire app.