Dave (00:01) Hello. Daniel (00:02) Hey, do you know, here, first thing I want to read to you. Joseph Hex says, I've been enjoying listening to the podcast for a while. This is a nice change to be able to see you too as well, because we're now on YouTube, we're also in your ear. Hi, Dave. It's fantastic to see you. How are you doing? Dave (00:07) Mm-hmm. We are. Hi. That's great to see you too Daniel. Yeah, I'm good. I'm really good. And yeah, it's good to get listener, well it's not even listener feedback now, it's viewer feedback on YouTube. Daniel (00:36) Chat, what chat, what do we think about that? Dave (00:39) Yes, it's kind of crazy, but it's also a lot of fun. I did not expect switching to video and audio to kind of be as immediately a fun thing. I think it helps that we've had video forever talking to each other, I think as well. The service we use to record all of this, we've had... Daniel (00:55) It is a fun thing, yeah. Dave (01:07) our respective video feeds to see each other with for a little while now. Uh, and I like that because it means I get the visual of what you're up to as well, and we can give each other feedback, but it's, it's nice to share that with the listeners as well. Daniel (01:21) It is. We are insanely grateful for all of, uh, all of the comments you post on YouTube and all of the emails that you sent us and all of the, uh, mass alone comments that you sent us, which are not super many, but we're, uh, that's, um, especially where we're so happy. And we're going to continue reading them out on the show as long as I feel, feel like doing that basically. Um, and on that note, Hey, welcome to Waiting for Review, a show about the majestic indie developer lifestyle. Dave (01:37) Yeah. Daniel (01:50) Join our scintillating hosts, Dave and Daniel, and let's hear about a tiny slice of their thrilling lives. Join us while waiting for review. Dave, I've been waiting for, not for review, but for my database server for the last, I wanna say six months, because every now and then it would just... Dave (02:02) Ayy. Daniel (02:16) crash and not produce proper data. And we call this the thorny data problem. Like I think the first episode that where I told you about this was actually called thorny data because you coined that term and I love it. And I now finally have it, I had it, I reached a point where I could reproduce the problem. I've bought it down finally to a single line of JSON that is about, I don't know, 40 characters long. Dave (02:26) Mm-hmm. Daniel (02:44) It's just two properties. One is a timestamp that just needs to be there for the database to accept the data at all. And the other one is a key and a value. The key is called a comma B. The value doesn't matter. Like the comma and the key is what crashes everything. Dave (03:04) Right, okay. Is that legit JSON? Is that key legit JSON? Daniel (03:06) And so that is finally the, well, at least none of the JSON parsing code that I've used to parse the JSON so far has ever rejected it. And I think, so that code only has been touched by the Python JSON parser, which I use in the ingest API. Maybe the Swift JSON parser would have rejected it. I don't know. Like someone else on Macedon when I told this story actually asked the same question, is that legal JSON? I don't know. Either way, commas are now replaced by underscores in keys. In fact, I have a list of allowed characters and everything else will be replaced by an underscore in the key. Because I don't want to take six months and then find the next character that's thorny. And with that, I finally managed to file a report or a bug issue actually with Apache Druid, with the time series database that I use. And it feels so good to finally have that down so far in that actually I can really see the problem. And because at the beginning I would just have to sit around and wait until the problem maybe showed up or not. Then after some time, I could see individual days were affected by the problem. So if I would ask the system to re-ingest or reload one of those days, then that would crash. But that still takes, I don't know, 15, 20, 25 minutes to load. And now finally, I can immediately make the thing crash. And that allows me to actually write a bug report. It's a bug. Apache slash droid issue 15736. I'm going to link it to the show notes just because I'm so incredibly proud of it. Um, yeah. And yeah. Dave (05:03) Yeah, please do. Well, I'm very glad to hear that, Daniel. This has been a, I mean, it's given us something to talk back to on the show and to kind of keep digging into each time. But I've been kind of gathering your frustration with this as well and the difficulty of the debugging itself is a round trip of like 15, 20 minutes of time, right, as you sort of try and figure this out. Daniel (05:27) Oh, you have... Yeah, yeah. And so, yeah, I've learned a lot on the way, but I'm really glad I'm this far. Only downside now is this. So I'm hoping that this will actually increase the stability a lot, and so I can go back to actually working on features and or performance. Only downside is this. There was a time last weekend when I thought I had found the issue. Dave (05:41) Ha ha Hmm. Daniel (06:05) But my fix was too broad. Like I just said, told you that I have a list of allowed characters, and I'm just going to make sure that the keys only contain the character. I applied that thing to both keys and values at first, because I thought it was in the values, and only afterwards I dug deeper, because I wanted to prevent the problem from spreading, Dave (06:17) Right. Mm-hmm. Daniel (06:28) Ah, two stories I need to tell, okay. So I wanted to stop the problem from spreading because at first all the thorny data that telemetry dick has came from two very tiny apps. I think I told you this last time already. So I was able to say like, okay, just special case those two app IDs and that's fine. But now suddenly, Dave (06:46) Yeah. Daniel (06:57) new thorny data came in and it crashed immediately, like on ingestion. So the error was actually different in that when the thorny data is in the historical data, then retrieving data doesn't work, which is bad. But if the error is in the data that comes in, in the message queue, then just like new signals won't arrive. They will just like pile up in the message queue. Also not very fun. So people would just like be like, ah, the last data I'm seeing is like five hours old. What's going on? Dave (07:20) Oh no. Okay. Daniel (07:28) Um, so, and that was an actual, um, that was an actual live app with, like, from a, from a larger customer that has more than a few, a few users. So I was like, okay, I can't just like, um, not deal with this. So I had a look at the data and there were commas in the, in the keys and the values. And so I was like, okay, I'm gonna, I, um, I just. right now assuming because the error message that I get, the crash, you have to dig a bit. You have to dig first into the one log file that tells you which server the problem is. And then you look at that server's log file that tells you which file the log is in. And then you can open that file. And that is the log. And there you have an exception. The exception kind of quotes part of a signal. So if I search for that string, I get one specific signal. And that always contained a comma. And so what's over here? I'm going to replace. both keys and values, like all the characters that are not in this list of allowed characters, I'm going to replace them with an underscore, and that's fine, right? And the allowed characters is like a to z, or a to z in both upper and lower case, all the numbers and underscores, maybe one or two more. Turns out that was very Dave (08:45) Thank you. Daniel (08:58) You know how we offer, for example, the ability to tell you which operating system you're running on? And the operating system is iOS space 16. And so that is actually, that's because now that's in the database. The database contains things like iOS under score 16, which Dave (09:17) Okay. Yeah. Daniel (09:25) is a completely different string than iOS Space 16. So you suddenly have more operating systems, which is kind of weird. And then also, yeah, which iPhone do you have? You have an iPhone 13,2. And that suddenly says iPhone 13 underscore 2. And that's what made me say, stop, wait. This has been a mistake. This was definitely a mistake. Dave (09:33) Mm-hmm. Yes. Yeah. Too far. Daniel (09:53) Because yeah, I went too far and I rewrote that data. And so what do I do now? The answer is, first of all, I do the thing that I now always do when something is wrong on the server or something is wrong in a very important part of the system that is not just code, which is I open Notion and begin a new document and just write down my thoughts, my assumptions, and all the error messages that I have. a fantastic tool and I told you about this last time as well, but I'm continuing doing this and it's just so incredibly helpful. And so I was like, okay, first of all, I'm going to revert that change where I replace the character so aggressively. Obviously, it's producing broken data, so I don't want that to happen anymore. And then, and so I was like, okay, if that one app is sending more signals, then... Dave (10:28) Yep. Daniel (10:52) so be it, and I will have to fix them using the old methods that I have now learned and that are in another notion document. Um, but, uh, with that, I, and then I'd really tried and I was like, okay, and now I really need to dig down as much as possible and really, really just find where this problem is. And so I, I finally, um, I I went to the documentation, found out various other forms of loading data into the system. And one of them is actually where you can just paste a single signal into a text box. And then it will just start the whole process and try to parse and ingest that single signal. And so I could actually prove to myself that, oh, yeah, that is the signal that is actually breaking the thing. And so from then on, it became just a process of paring down that signal further and further down until I had it down to one key value pair, if you count for the timestamp. And then I could play around with those strings and prove to myself, yes, it doesn't matter what the value is, if the key has a comma, that is what's producing the thing. And so then I could really create the right amount of data changing, data fixing for the ingest server, which is have a list of allowed characters for the keys. but not for the values. Well, the values also have a lot of characters, but that's like way wider. So yeah, now I have two and a half days of data that is not perfectly right. And that bugs me. So I loaded the data. I wanted to download the data, but it turns out it takes a day to just download it to my computer. So instead I created a VM in the cloud Dave (12:21) Hehehe Daniel (12:44) added a 3 terabyte virtual hard drive to it. And so what I've done today is I wrote said scripts, said SED, which is a, it's the Unix Stream Editor. That's what SED stands for, I think. And yeah, that will just basically rec access. Dave (13:08) Okay. Daniel (13:13) that will find the broken data, or at least as much as I can like describe with regex, find the broken data where I'm like all those instances where I'm really sure that what is actually broken and in what way, and then try to set it right. And yeah, so as we are, like I have tried this out with smaller sets of the data, and as we are speaking actually, it is running on the thing in a screen session, because if my SSH just disconnects, otherwise it will be broken. And we are, let me check, we are at about 75%. So it might actually finish by the time we're actually finishing. And so then I will have on that hard drive, I will have fixed data. Dave (13:59) That's awesome. Daniel (14:02) And then like, I will have to re-ingest it, of course, but that's awesome. That's I'm a, I'm a professional at that. So my life, which has been, which has been like, has had, has had so much frustration because of this bug for the last half year and for the last month, for the whole month of January, like this problem has been actively frustrating me and like robbing me of nights and weekends. Our long national nightmare, Dave is finally over. Dave (14:09) Hehehehe Yeah, that's rough. Yep. You are finally getting these thorns out of your side. As it were. Daniel (14:36) Hahaha Everything is just a tiny bit nice. Dave (14:43) Excellent, excellent. And that's, what a way to go into the rest of the year, right, when you've managed to slay one of these longstanding things. I'm trying to turn it into a positive for you, Daniel. I know how frustrating it's been over this time. Yeah. Daniel (14:49) Yeah. Oh, I am so happy. I am so happy. Of course, I would have loved to find this earlier, especially like I am a reasonably experienced software engineer. I should be able to debug stuff. And now that I know the solution, I'm going back into my notes and finding that, oh, yeah, at the very beginning, I had an inkling that, oh, yeah, maybe I will look into this part of the log or whatever. And had I done that, Dave (15:11) Mm-hmm. Yep. Daniel (15:25) And then followed up directly, then I would have like found this way earlier, but, um, yeah, sometimes it just takes a while. Dave (15:34) Yeah. Sometimes you've got to go around the long way to them really, really feel like you've landed it and to understand the issue. Again, like, okay, I'm trying to turn this into a positive. It is a positive. But sort of thinking about everybody listening in, like, we've all had these moments, like in the course of a, a deaf career of any length, you do end up with these sort of like, um, Daniel (15:40) Yeah. Dave (16:03) I want to say almost kind of Moby Dick kind of-esque bug hunts. I've run into a few with Guy Vijay with my video mixer because AV Foundation has got a lot of different bits to it. It is absolutely possible to call things to stutter if you block the main thread with video. Daniel (16:07) Hahaha Dave (16:31) It's very, very easy to end up in that sort of an issue. And certainly in my first round of dev back in 2014, obviously devices were not as powerful as they are now. It was very, very easy to do stuff that would then end up with a random frame drop or, in my case, the one that was similar to your situation, I think, in terms of the time it took the type of issue was that I had a, an issue with when you hit, when you start playing a video, it would have a lot of lag before it played. Yeah. So if you think about what's going on with like a, an app like mine, you want to press the button and the video plays, right? You don't want any latency at all. Daniel (17:13) Ugh. It's frustrating. Dave (17:28) In fact, I never really solved it back in 2015. It's kind of amusing if I think about it. I quote unquote solved it by having a drag and drop paradigm on my user interface. So you drag the Daniel (17:43) Okay. Yeah, well, sometimes that's the solution, right? Dave (17:50) Yeah, it was and it kind of was the solution. And so, you know, if you think you sort of pressed on the video to select it and then would drag it up into one of the slots to play it on either channel, that was just enough kind of latency in the user interaction that people didn't notice the latency in the video actually starting. Yeah. Daniel (18:02) Mm-hmm. Fantastic. I love that idea. You know what that reminds me of? When I was a young boy, I used to play a game called Wing Commander. I think Wing Commander 4 maybe or 3, something like that. And famously, Wing Commander was the game that whenever you selected quit game, they discovered during development that would cause a crash. And so... Dave (18:30) Mm-hmm. Daniel (18:42) the user would go back to the command line. That was back in the days of the DOS command line. The user would go back to the command line and would see an error message that says something like, hey, WingCommander.exe just crashed at a memory address such and such. And so what they did was they wouldn't, they weren't able to find the issue. So what they did was they changed this error message to thank you for playing Wing Commander. And so that would display every time you quit the Dave (18:55) Mm-hmm. Yep. Oh, that's brilliant. That's brilliant. That's, uh... Daniel (19:14) And so of course, if you encounter an exception in the logs or whatever, it would also say thank you for playing Wing Commander. But I mean, it worked. Dave (19:24) Yeah, that's the sort of thing that you could probably use a macro or something so that you have a dev version that doesn't give you the error message, right? But honestly, if I think about it though, that fix that I found at the time, it was like a Bob Ross moment, right? Oh, my UI is like this, and now everything's magically working. And I'm like, oh, cool. Happy accidents. Keep moving. Daniel (19:46) Mm. Mm-hmm. Dave (19:54) Um, and I guess to some degree, I thought I'd solve the issue in amongst my other fixes and attempts at optimizing the engine underneath. Uh, only to be faced with the fact that when I then went and it's been through several successive rewrites, right? I've had, um, the Objective-C version made back then. Then there was the Swift port of it a couple of years later. Um, which was almost. It's literally just a direct translation of the objective C code. And then two years ago, I was pulling together the current version of GoVJ. And within that, at the time I was programming in the router design pattern. So the UI and everything is all in the design pattern that I laid out for that. But really at that point in time, two years back, the big deal was that I found some of the issues that were causing this latency. And effectively, I can't really get into the depth of it even now because I found it, I fixed it, everything sort of clicked into place. So I was like, yeah, cool, this is working. Daniel (21:00) Ooh, what were the issues? Is it because you're under NDA, Dave? Is it because you cannot tell? It is a secret. Dave (21:16) Uh. Oh no, no. Sorry, that creep. ASMR style Daniel whispering. I'd love to be able to claim I was under NDA for my own app, Daniel, but unfortunately not. No, there's nothing secret about how I fixed it either. It's no secret source for anything, but yeah, it's been a while and I can't remember is the honest answer to that. Daniel (21:20) Hahaha Yeah. Dave (21:45) And that happens to, right, you end up fixing these things, you're three levels down, and it's only when you're actually back there that you can really explain what you've done. But anyway, I fixed it. That was a couple of years back. SwiftUI router version went live in July, I think it was, 2022. That also marked the change into. Daniel (21:48) Yeah. Mm-hmm. I remember we talked a lot about that at the time. Dave (22:14) Yeah, yeah, yeah. It was a change into a subscription model for the app as well. So, and that's been live ever since then and I've added to it, I've updated it, but I'm kind of, the reason I'm talking about this Daniel is this links right into what I'm doing right now. I am once again rebuilding my app. But it's true. This is what I'm doing. Yep. Daniel (22:19) Mm-hmm. I was trying to segue into that. Yeah. How, how was it? How's the, how's that fairing? Like, how's it going? What are your goals? Dave (22:47) Well, yeah, OK. So for context, two years ago, I used the router design pattern, which is what I was using in my day job at the time with the team that I was managing. And it was a very effective pattern for that world. It's where you, the main principles of it, if you like, is that every screen is labeled as such. So SwiftUI, everything's a view. Well, I would specifically call the view that represents the whole screen a screen. It would have a protocol that it would use to talk back to its router. And the router was effectively a glorified view model with an observable object backing it up. And routers would be like that. They would have this view model component that sort of managed the whole state if you like of a flow and the route would also be responsible for creating screens and giving those views back to the view layer. All very nicely separated. Bit of a like minimum viable separation. Daniel (23:48) Mm-hmm. Was that in between question? Sorry. Was that before SwiftUI, or does that work with SwiftUI 2? Dave (24:05) Mm hmm. Cool. with only with SwiftUI. So the design pattern here was very much a case of me trying to assert some level of design pattern control over SwiftUI. And I've got a blog post about it actually. I'll put it in our show notes. We'll link it all up. But I had a blog post that guided people through what I did, an example repo, I even had Xcode templates. for the router and for the screen and view model pairs. Brilliant. However, really, really cool when you've got a team of say four or five people trying not to tread on each other's toes. Yeah. Really, really cool when you want sort of minimum viable dependency injection outside of Swift's environment layer and so on and so on. Not so cool when Daniel (24:52) Yeah Dave (25:10) you are a solo indie dev trying to just get stuff done. So it's one of those things where it was easy for me at the time to lean into the design pattern because I was using it day in, day out, and using it in a side project was helpful. And we sort of touched on this in the last episode, as well as that I sort of end up with a historical sedimentary layer of design patterns in my side projects, right? Daniel (25:35) Mm-hmm. Dave (25:37) that are representing what was useful for me in my day jobs at the time. So this current refactoring is kind of a factory reset. And yeah, to explain that better, about, I wanna say six months ago, again, we spoke about this at the time, but as we were heading up for a house move, I stopped working on my apps. Daniel (25:51) Oof. Dave (26:06) for new features. And I started making the Lego block Swift packages that I've been using for things since. Yeah, and they are Swift packages that have got things like, you know, a settings menu that can, a setting screen that can be configured. I've got a paywall package where I can drop my standard kind of paywall in and wire it all up to revenue cat and so on and so on. Daniel (26:07) Mm-hmm. Right. Mm-hmm. Dave (26:33) And one of the things I did when making these packages is that I went, okay, I'm not going to use any specific design pattern here. I'm going to use effectively Apple default. Everything's in Swift UIs view layer kind of approach. Uh, so no fancy dependency injection or anything like that. I'm using the environment. Brilliant. Uh, and I found that there was a lovely sort of fluidity that started to build up and I was like, right, okay, I get it. I get why Apple sort of do it this way. Whereas maybe two or three years ago, I just didn't. And that has had a knock on effect. So that now I'm sort of coming back to add stuff to GoVJ and I'm like, oh my God, it's got this design pattern that's actually slowing me down. So I'm ripping it out. I'm raising it to the ground. Yeah. Daniel (27:10) Mm-hmm. How bad is that? Like how much work is freeing one view of the router pattern? Dave (27:33) Yeah, which may not. Well, hmm. It has cascade effect, right? Because as soon as you get rid of one bit or you try and change one bit, you've then got to solve the flow-on problem of, well, now this doesn't connect to anything. So I'd end up quite literally with screens where they've got, say, a back button or a dismiss button and that it doesn't work because there's no router to listen to that response to then go and change the presenting value. Daniel (28:05) Mm-hmm. Dave (28:12) And so you sort of solve one bit in a screen, and then you've got to come back up to the router level and remove that bit. And then that cascades to the other screens that the router held onto. And so what's happening really is that I'm ending up in these kind of very deep weed whacking kind of sessions with a router and its associated child views. Like I'm having to go sort of block by block, flow by flow. Daniel (28:40) deep in the jungle with your machete and just like trying not to get lost. Okay, but the code, the view code, like the layout code, that you can reuse that, right? So it's not a complete rewrite of a view or something. Dave (28:43) Yeah. And it's, yeah. Absolutely. Yeah. Yeah. And there's a whole bunch of different concepts that I've got a sort of way here as well. So I had a dependency injection method where I'm using property wrappers. And so I can just, I've got a property wrapper called injected. So I just write at injected and then off there, I can then call down using key value paths in brackets after that, the thing that I want. to bring down into the view model, typically. And I've not changed that. There's no reason to change that. The only thing that I have changed there is that in some cases, my router would be creating the view models and giving them to the views. And so I'm shutting that door. There is no more of that responsibility. And that means a view has to create their own view model on instantiation, as it were. And there's some edges with that, right, just in terms of if there was ever anything that the view model was configured with from the route. So then I've got to push it down a level. So I'm solving all these problems and it's kind of like everything everywhere all at once, right? You know, you fix that one bit, this bit doesn't fit, you've got to fix that bit, then that bit, and then eventually it compiles and you run it and you test it and you go, yeah, okay, these things are no longer wired up properly. I've got to make sure that now I'm Daniel (30:12) Hehehehe Dave (30:25) I don't know, this button presents the sheet at the right level or dismisses things appropriately or whatever. So it's kind of like I'm ripping out what feels like somewhere between a third to maybe 40, 50% of the code and rewriting in the UI layer. Yeah. So there is a point when you end up doing jobs like this. Daniel (30:44) Hmm Alright. Is that fun? Or is that a chore? Dave (30:55) Yeah, it's largely a chore. It's fun when it's done, and it feels like fresh snow when it's all done and you look back and you're like, ah cool, yeah, that works. Daniel (30:59) Ah. Hahaha It's like when you clean in the kitchen or the whole apartment is just like done and you're like, oh, this is so nice. Dave (31:15) Yes, but in the meantime, to follow that analogy, it's like you start with a view and you make a clean spot. And then that entire side of the kitchen then needs to be done because you've made one clean spot. And you know bit is happening in bits by bit. Like each router is a different work surface. So eventually I'll have a clean room and users won't be able to tell any difference. if I've done my job properly. So the question then comes for why bother? Right? The app works. Why not just leave it as it is? The honest answer to that is that I wanted to make this change but the logical underpinning if you like is that as I wire in these Lego blocks it makes more sense if the rest of the app is sort of working in this Daniel (31:47) Yeah. Dave (32:15) much more like Apple default, SwiftUI way of working, if you like. Um, equally, I suspect my suspicion here is that by sort of choosing that as my lowest common denominator, it kind of doesn't really matter what design patterns I'm using in my day job as it were, right? They're there, this is here. Uh, and I think that's going to be useful in the course of time. Daniel (32:34) Yeah. I feel that, especially because you say like, oh, yeah, it's just like, you need you don't need to do it. But what this enables you to do is it enables you to keep your motivation and your velocity high. And those are really important, especially because this is your side project. So because it's your side project, you want to make everything as easy as possible for you and you may you want to you need to make it like especially you haven't Dave (32:55) Mm-hmm. Yes. Daniel (33:08) worked on it for a week or two and you come back. And now if you have to really get into a complicated pattern again, that may be hard. Whereas if it's just like, oh yeah, everything is easy to do and you can touch everywhere and just immediately get a cool result, that is definitely worth something. And on top of that, it is your side project. So you're allowed to do things that are just fun or just want to do them. That's the other thing. Dave (33:15) Mm-hmm. Absolutely. Absolutely. Yeah. And I think the thing here is it's a bit of preparation as well. In terms of, I'm going to be working on Govj Pro in another month or two. That's my plan. And before I get into the sort of Govj Pro mode, if you like, I want to have everything kind of standardized here. Oh yeah. Yeah. Daniel (33:56) So wait, so the decision has been made to go forward with GoBJ Pro? Oh, it has been made! Fantastic news! Dave (34:07) Mm-hmm. I've had a reasonable amount of feedback from the landing page, like enough to show me that there is some interest there. And there was an element of this was always going to happen in one way or another. Right. The only thing up for debate was whether I would do it over a longer period of time or a shorter period of time. Right. And what I've realized is there's enough interest out there for it to be worth me giving it a shot. And I have enough personal interest and motivation to really give it a good go. Like the design that I made for the landing page, I'm kind of in love with it. I keep thinking about it. It keeps pulling me back and I'm like, Oh, I've got to build the thing. I've got to build the thing. Um, so weed whacking the original go VJ code base is it feels like I'm sort of limbering up for that as well. So. Daniel (35:06) Yeah, I get that. Dave (35:07) Yeah, I mean, I don't think I'm going to have a shared code base, but the video library that is one of my Lego blocks that I've been working on for the last six months, that doesn't exist in regular Govj today. I've got the old version of the library there at the moment. So by doing this sort of refactor, I will then, the final stroke of that is to then patch in the new video engine. Daniel (35:27) Mm-hmm. Dave (35:39) And what that will do for me is that will let me kind of road test wiring up this video engine to a set of controls in an existing app with existing behaviors. And I know for a fact I'm going to have to refactor some of the video engine. So but at the moment I don't quite know exactly how that's all going to come together. So if I do it with the existing app. Daniel (35:50) Mm-hmm. Dave (36:05) It's a known quantity. I've got known expected UX and behavior. And that will let me tune the engine's hooks, if you like, for the UI. Before I'm building a new app. Daniel (36:15) Mm-hmm, but it doesn't give you the fun of just rewriting everything. Dave (36:21) Pardon. Daniel (36:22) but it doesn't give you the fun of just starting from Dave (36:28) Uh, no, which will be the new pro that'll be the, that'll be the new project and that's okay. Um, but what I'm saying, you did, you totally did. We also had a little bit of lag in the call, uh, which shouldn't be noticeable when this all comes together for YouTube. But, uh, you, because the way the service works, um, I get a lower quality video call while we speak and then the higher quality gets uploaded behind the scenes. Um, Daniel (36:30) Hahaha Did I derail your train of thought there? Sorry. Yeah. Dave (36:56) Anyway, sorry, Daniel. Yeah, I skipped out as you were talking, but I think what you were saying was that doesn't give me the fun of a whole refactor, a whole rewrite. Daniel (37:06) Yeah, exactly. Dave (37:09) Yeah. So that's okay. I mean, like what I'm saying here though, is I've got my video engine is sort of ready to go. At the moment though, it's not battle tested. It hasn't really been used in any anything other than test apps. So by bringing that back into the existing app, I will be able to kick its tires without also worrying about the UX of a new And then that should hopefully mean that I can go straight into the pro development and everything sort of good start using straight out of the box. So we shall see. Daniel (37:47) Yeah, I think there's also the right approach. So I said earlier, yeah, that doesn't give you the warm, fun feeling of rewriting everything. But I think one thing that we have said on this show again and again is that rewriting everything is usually more work than it seems at the time. And it's mostly not a good idea. Like if you really wanna rewrite everything, Dave (37:56) Mm-hmm. Mm-hmm. Daniel (38:14) Like go ahead, of course, but like it's probably not the right idea. And I think, um, like it's also not the right idea in your case. Like, especially if you have all that UI already to work with this stuff. So yeah, that's exactly the right approach. I Dave (38:32) It'll let me test out a few things, right? I've not just got the UI to consider with this sort of an app. I've also got the MIDI layer that I added last year and how that interacts with the video mixing engine that you're controlling. I want to extend that and add game pad and joystick inputs as well. So you can use like a PlayStation controller with the app. Daniel (38:57) Hmm. Dave (39:01) That's a whole other thing I'll get into later in the year, I guess. But yeah, I guess all this to say at the moment, it feels like I'm editing a lot of code, that I'm rewriting a whole bunch of stuff. It's kind of not very fulfilling, but the end goal is. And hopefully I'll be a bit more enthusiastic about where things are, sort of when we catch up in a week or two. But these things are things that devs do. Daniel (39:24) Hehehehehehe Dave (39:30) every now and again, these are things that I think we all sort of think about in one way or another, even if it's just a case of like, well, I've made version one of the thing, and actually version two needs to take so many things into consideration, I may as well start again, for example, right, you sort of end up in that kind of stage quite easily, quite often. Daniel (39:46) Yeah, I like to think of that this is basically what the phrase technical debt actually means. Like, some points in the development, you know you're not doing everything perfectly right, because that's just not where your app is at, or that's not where your company or you as a person are at. So you do it the best way that is appropriate for the situation, but that means you incur technical debt. Dave (39:57) Mm-hmm. Daniel (40:15) And then at the later time, you pay it back with one of those weed whacking sessions. And that's just the way it is. And it's just, you just got to accept that this is also part of, uh, sometimes you need to clean your house. Dave (40:28) Yes. And I think I described this once in a corporate kind of setting where I needed buy-in, right? I needed buy-in from product owners and various other people to actually go and pay down some technical debt before we could start adding new features. Because I knew that if we added a whole load of new stuff to what existed, it was just going to be like a very unstable stack of cards after a point in time. Daniel (40:44) Mm. Yeah. Dave (40:58) And the way I sold it to those people at the time was I turned it on its head and I described it as technical credit. Right. So, uh, I said that rather than it being technical debt, we have to pay because we owe it, what we're actually doing is we're getting ourselves into credit to be able to add new features. It was. Daniel (41:07) Okay, tell me more. Okay. Dave (41:27) a very kind of political sleight of hand if you like but they really love this idea of it's not technical debt it's technical credit pay it now and we can do nice things Daniel (41:37) Oh yeah, debt is bad, but credit is good. Yeah, I can see that. Maybe we should all as a community embrace that. Dave (41:43) Yeah, yeah, yeah. Daniel (41:47) Like if your development is slow, it's not because you're in debt, it's just like because you haven't built up the credit. Dave (41:49) I still like the idea, right? Yes, yes, exactly. And so there was this idea of like, getting yourself into credit first before then being able to go and do a lot of new things. It's the same concept, right? You know, you're either paying your debts before you can move on, or it's getting some credit upfront to give you a buffer to do good things like. it doesn't really matter, you're sort of describing the same process, you've still got to go and do the refactor or whatever it is to make things stable, but it was a good vehicle for those people around me to understand what we were doing and to understand it wasn't because the code base was bad. I think that was the big issue, if you like, that sort of explanation of like, well, why do we have to rebuild things? Did we not do it properly the first time? And it's like, we did. within the realms of what it was doing. We are now trying to get ahead of ourselves, if you like, to lay down the groundwork for the next thing. And that landed well at the time with those people for me. Daniel (43:05) Very good. I like that. Dave (43:05) But on my own, I don't need to sell myself on this, right? I'm already in. But I think I am seeing it through that lens, right? It's not like, oh, I've got to rebuild this because it's absolute rubbish. I'm shoring it up so that my next round of development for the rest of the year is going to be a much happier sort of place, a much more stable kind of place. uh, son. Daniel (43:35) Yeah, it makes sense. For me, it's always the clean house metaphor, basically. Like if the whole building is in rubble, I need to do a lot of build up work. But like, if the building is sound, but this is just like, everything is like, the walls are dirty, then I need to paint the walls. But if everything is like stable, it's just like, there's like, it's just messy. Then maybe I will have to clean it up. And maybe like today is not the day where I clean stuff. Dave (43:38) It's a bit of a grind. Yeah. Yeah, exactly. Daniel (44:05) Yeah. We wanted earlier and I stopped you because we weren't recording. We wanted to talk about watch bands or watch straps and, um, Dave (44:12) That's so good, that's so good. I think that would be a nice way to round out the show actually Daniel. So just for viewers, they'll be able to see in a second and for listeners will describe it. But it just so turns out we're wearing the same type of watch band. Daniel (44:19) Yeah. Yeah, we're wearing the same. Yeah, exactly. Um, it's the, it's the sports band with the holes. I, is it the Nike band? I don't know. Uh, yeah, minus, minus. Dave (44:34) We are Yin and Yang. Yeah. So I've got the black one. Daniel's got the white and black one. Daniel (44:46) Right, exactly. And I was saying that this is actually one of my favorite watch bands because it just feels very nice on your skin and the holes mean you're not sweating. And I recently though, I recently discovered that I do like the, I forgot the name. I forgot the name again, even though I Googled it earlier. I really, really like the fabric one, the sports fabric band. Hang on, I actually, I have the page here, the sport loop. Dave (45:09) Fabric? Sports fabric band? Yeah. Daniel (45:16) That's the one. And I never bought a sport look because just from the pictures, it just doesn't look like comfortable to me. It just doesn't look good to me. I'm like, what is this? And then a few months ago, I needed to wear a suit and I wanted to have a watch band with like that fit with the color. And so I just popped into the Apple store and was like, okay, what do they have? That is like... Dave (45:17) Spot loop, okay, yeah, yeah. Daniel (45:44) a single shade of dark color. And I settled on a midnight colored sport look. And what can I say? This thing is so incredibly comfortable. Like, it's amazing. And like, I always thought it would be scratchy somehow, but it's like really soft and that caresses your skin in a very nice way. And yeah. Dave (45:52) Hey. Ha ha ha. Daniel (46:14) And then even like, I was talking to Lisa about this. Um, and, and she was like, yeah, I like Apple watches, but like she has, um, very sensitive skin, like she has a thing, I think, uh, where like pressure on her skin is like, especially bad for her. And so she was like, yeah, she likes her Apple watch. She recently got one, but it's actually like not perfect to wear. And so I was like, okay, you know what, let's switch bands for a second. And like here you can wear my sport loop for. until we meet again like in a week or so. And so yeah, and like I hear good things from her as well. So I'm thinking maybe at some point, yeah, probably. I'm thinking at some point I need to like buy another sport loop. And also what I really want is actually one of the, like you know the Apple Watch Ultra has this bright orange band. I really want that, but I don't have an Ultra. Dave (46:53) You're never getting that back, Daniel. Yes. Daniel (47:14) So I probably won't be able to, but I love that. I love those, the Apple Watch Ultra bands. Like they're just nice. Dave (47:15) Okay. just having a look now. Yeah, they're the you can buy them, but they are for the ultra. That's right. And that's Daniel (47:26) The ocean band, orange ocean band. You need a 49 millimeter watch, which is the ultra. Should I get an ultra? I should probably get an ultra, right? Dave (47:36) Yeah. Don't ask me that. I'm an enabler. I will turn around and say, just get it, Daniel. It's beautiful. Do it. Daniel (47:42) Hahaha No, the thing is, I'm wearing the 41 millimeter watch. That's the smaller one because I have like little dainty wrists. And also I like how it looks on my wrist. But at the same time, I'm really getting back into cycling. And right now that is mostly indoors, but at some point I'm going to go back into the mode where I spent like basically an entire day on the bike. And the watch... Dave (47:52) Mm-hmm. Yep. Daniel (48:15) the normal 41 millimeter Apple watch can do that if it is less than a year old, or if you disable always on screen. If it's like in my experience, if it's more than a year old, so that the battery has just has gone through a lot of cycles, it will probably not make it. And then you have this choice where it's like, okay, it's been like six hours of like sporty activity. Do I turn off the activity? Dave (48:27) Okay. Daniel (48:45) so that it gets saved or do I continue and risk losing it because the watch will just turn off at some. Dave (48:48) Mm-hmm. Ooh, I don't like the anxiety with that. Daniel (48:56) And so, yeah. And so I've been thinking, huh, should I get an ultra? But then I look at the prices and then I'm Dave (49:09) Ah, yeah, don't get me started on Apple prices and things. Daniel (49:13) Oh, but look at that. Oh, Apple fine woven. So I always wanted. Dave (49:19) You've already sold yourself, haven't you? Ha ha ha! Daniel (49:23) So, Apple used to have leather bands and they don't sell those anymore because they say they're going away from leather because of the environment and I assume animal rights. And so now they've replaced this with fine woven. And they never had the blue leather band, they never had that for the 41 millimeter watch. They always only had it for the bigger watches. And now I'm seeing here on that page, because of course I'm browsing the Apple store, is they have the Pacific Blue Magnetic Link fine woven band. They have that in my size and it looks really nice. But at the same time, I'm hearing everyone is talking about the fact that fine woven is like very easy to And this is like a hundred bucks. So I'm like, ah, maybe not. Dave (50:22) Yeah, I saw a lot of feedback on Fymewave, more not feedback, people posting to Mastodon and things saying it wasn't very much good. So I would have reservations about that for sure, about going all in on one of those. But the Ultra itself though, Daniel, everyone I know who's bought one loves it. Daniel (50:44) Yeah. Yeah, yeah. Dave (50:53) So yes, it's expensive. But yeah, if you're out there doing lots of sporty activity this summer, I reckon it could be worth it. Daniel (51:05) Yeah, if you want to support me, get a Telemetry Dexo Dave (51:11) We'll always be selling. Daniel (51:13) Always be selling. No, but if you listen to the show and you have a fine-woven watch band, I really would like to hear from you how it fares in your day-to-day life. Dave (51:25) Yeah. And I would say whatever social media or platform people find have found us on, they should at you if they think you should get an ultra. I think we should pressure peer pressure, Daniel into making an expensive purchase. Daniel (51:26) Also Dave... Yeah. I'm out. Ah, thank you so much for that. Um, yeah, please, please zoom, please. Let's just peer pressure me into spending money. Um, Dave, what band did you get with your vision pro? Because like mine arrived, my vision pro arrived just yesterday because it's like February three or four or something when the, when that, when this episode is released, right? Dave (51:44) Hehehe Mm-hmm. Yep. Daniel (52:08) So I got for my Vision Pro, I got the RMS double tour strap for my head. No. No, no. I almost, I'm not getting a Vision Pro. I don't think it would be right now at where I'm at with my life and with my development story. I don't think it would make a lot of sense for me. Dave (52:15) You're getting a vision pro Daniel, for real. Don't stop. Uhhh Yep. My accountant said no, basically. On that note, Daniel, I'm afraid I'm going to have to wrap up for today. And I am very much deciding to leave this before we talk more about the Vision Pro. We can talk more about the Vision Pro on a future episode, I think. Daniel (52:49) Hehehe You're just afraid of the thing that I have in the topic Dave (53:07) Yeah, there's a question in our topic document. Daniel (53:10) You said you would swear at me as soon as I asked you those questions, so I'm very much looking forward to doing that. Dave (53:18) that's not this show, that's another time. And I'm not sure I'll swear at you, but yeah, it'll be a hopefully an interesting thing to talk about is like why the Vision Pro or not. Daniel (53:21) That is another time. Yeah. Oh yeah, before we go though, before we go, earlier, earlier when we started recording, your microphone gave out, but your video was still visible. We like that was, there was a suggestion that it was quickly rectified. I only saw you when I didn't hear you, but I saw your mouth for me. Very, very bad words. I was like, yes, I recognize that. Dave (53:39) Mm-hmm. It started in F and ended in F I believe. Um, yeah. Yeah. Uh, people shouldn't be surprised. I, yeah, I definitely swear a fair amount. I try and avoid it on the show, but uh, sometimes it slips out. Yeah. God. Daniel (53:58) Hehehehehehehehe I'm a lip reader. Fantastic. If you can read lips or if you wanna talk to us about the Vision Pro or Apple Watch Ultra or our development journey or if you have a question, please write us at contact at wait Follow us on YouTube, on where you get podcasts, on threads, on Instagram and on TikTok. Dave (54:40) Mm-hmm. Daniel (54:41) because we're everywhere. Mostly we are WFR pod, but otherwise just search for the name of the podcast. And you can also write us directly. Where can people find you Dave? Dave (54:52) People can find me on Mastodon and the Fediverse at dave@social.lightbeamapps.com and you can find out more about my apps just at lightbeamapps.com. How about yourself Daniel? Daniel (55:05) Yeah, please buy the biggest subscription on telemetrydeck.com if you want to enable me buying lots of stuff and also write me at daniel at social dot telemetry deck.com You can write me on mastodon and I haven't blocked threads so you can also write me on threads at that account I think that's possible now I'm not 100% sure like if you if it is please mention me. I want to see how that works All right, Dave have a fantastic day and see you soon Dave (55:34) Yep. Cheers, Daniel. Catch you again. Daniel (55:37) Alright. Byeeeeee