Jon (00:06.262) Welcome back everybody to Gone Mobile. Today, Alan, I wanna pick your brain a little bit and see how you've been getting along with all of your migrations. Allan Ritchie (00:17.966) Picking my brain. That's dangerous. Well, you know what? I've been having success for a while. I think.NET 6, Maui migrations weren't going so hot, but.NET 7, especially.NET 8 has been pretty darn good. Yeah, customers are in a panic now. They don't need to be, but they are. I've got one really awesome customer though that's... Jon (00:19.52) Yeah. Jon (00:37.582) So you're picking up some steam. Allan Ritchie (00:48.518) They're just doing the migration now because they've got a, I don't want to say downtime. That's probably the wrong choice of words, but this is their time to migrate. Jon (00:57.813) their offseason. Allan Ritchie (01:00.619) Yeah, they're wanting to do features, but it's just, they just, this is the time to do it for whatever reason. And once they get that done, they'll be, you know, cranking features out. Jon (01:11.926) I'm mostly through my migration of my pool app. Finally, it's taken a long time and I, you know, I've, I have, of course, yeah, like took the, the long route of let's not only just like migrate from forms to Maui, let's actually like re-architect the underlying bits and everything. So, uh, I feel like I chose the hardest route possible to, to migrate the app. I don't know. Are you finding people are doing that too? Like, is it an opportunity that. Allan Ritchie (01:18.918) You'll never be through it. Allan Ritchie (01:36.426) as you do. But that's all right. Jon (01:40.306) Some are using to say like, let's like clean things up. Allan Ritchie (01:44.234) Yes, and there's several reasons for that. One is obviously a lot of people that I work with, they usually end up being enterprise or large scale apps. So most of them, not all of them, end up using some form of dependency injection. People that generally tend to reach out to me, you shiny, and I force dependency on dependency injection on them, whether they want it or not. So Jon (01:53.067) Mm-hmm. Allan Ritchie (02:11.962) lot of people are taking advantage of that now because it's out of the box. So they love that. So they're doing a lot of stuff and clean up there and getting rid of all those static untestable components that they've got. But really just taking the opportunity because obviously the whole mobile space has advanced quite a bit since I don't know since they're Jon (02:17.206) Yeah. Allan Ritchie (02:40.046) When did Xamarin.Forms come out? 2014? Later? Jon (02:40.301) Yeah. Jon (02:45.93) Oh, I think probably around then I'm trying to think of there was one Xamarin evolve conference that, so I actually, this is a funny story. Um, at the time I was the components team. I was on the components team leading. I don't know. Uh, I was, I was doing components stuff like bindings and things. And so I had a talk prepared for, I think it was the Atlanta conference. That we had a Xamarin evolve. I don't, did you ever get to any evolve conferences? Allan Ritchie (03:16.174) first one in Austin was fantastic. Jon (03:16.95) The first one, okay. I didn't, I didn't, I didn't, I guess we didn't really cross paths there a whole lot, but yeah, I was at that one too. But I was not yet, I think an employee of Xamarin at the time. So. Allan Ritchie (03:30.507) That was the person I ended up crossing paths with was David Ort now. Back then he was a lot quieter than he gets tired of hearing that story. I'm like, man, you get louder every time I see you. Jon (03:36.875) Yeah. Jon (03:40.742) Oh, he sure does. Yeah. We love David. Um, most of the time. Yeah. No, just kidding. Yeah. So, uh, at that conference I had a talk scheduled and it was in like, you know, not that big of a room. Like I forget how many people were at those things that one, it was probably 600 or maybe it was 1200 or something. Like it wasn't a huge conference, but it wasn't a tiny conference. Allan Ritchie (03:45.55) Yes. Jon (04:03.154) And so I had to talk on, on the think Google play services and, and how to use them in your apps. And that was more like an Android thing, I think. And I had a certain size room and that was the year that forms really exploded in popularity. And so what happened is like this whole thing that was forms, which was started as, you know, with this code name Duplo. And it was just, the idea was actually originally just, can we build something people can use to like rapidly prototype an app, not necessarily expect. Allan Ritchie (04:03.216) Yeah. Jon (04:32.354) people to use it to ship their app with. It was really designed just to be like a tool to help quickly throw something together so that you can move on to the actual phase of building your app with the native controls and everything. But it was so popular of a concept at the time that people were just like, oh, I wanna use this. And we quickly realized like, oh, like this is more than a prototyping thing. This is a product and like people expect to use it that way. And it was at that conference at that time that, you know, things shot up. And I think what happened is that they had a ton of people registered for Jason's talk, which was in the same time slot as mine, but I had the bigger room of the two places. And so they decided like last minute to go ahead and switch the room so they could fit more people into that one, you know, which is, it was great, but it was kind of funny and really sad because I'm sitting there at the front getting ready and as people are coming in, I'm like, yeah, if you haven't heard, like they've moved. the forums talk to this other spot and I'm here now. And then some people just kept coming in and being like, Oh, okay. So sorry. Bye. Right. Like everyone just like leaving. Um, you know, there were some people that stayed too, which was nice, but it was, it was kind of funny. It was like, Oh, and that couldn't even go watch the talk either because I had to do my own thing at the same time. Um, but that, uh, yeah. Yeah. It was, it was rather funny. And, and people were so like, uh, nicely apologetic too. They're like, Allan Ritchie (05:37.338) Hehehehe Allan Ritchie (05:47.814) It's always fun, isn't it? You're like, oh, people are leaving. Jon (05:57.738) This sounds cool, too, but I really want to go see that other one. It's like yeah, you know, you're good. You're fine So that was kind of the that was I think 2015 ish and that was kind of the start of forms and like I said, that was what forms was originally meant to be and Of course since then, you know fast forward it has evolved like crazy and to the point where now we are You know Maui not just forms and Maui. I think we always try to explain as the evolution of forms. And so it's a lot of pieces of forms, a lot of code from forms carried over a lot of different parts and ideas. But we took the thing that every developer loves to do, which is like, Hey, if you get to make some new decisions, what would you change? Right. And so the big thing that we changed, I would say is, is the architecture of how we use these things called handlers now, which if you were familiar with forms, if you wanted to customize or if you wanted to implement your abstraction, so you've got a button, well, what does that map to on each platform? We used to have these things called renders and the idea was to connect those two concepts up. And now with Maui, and this is still before I kind of joined on the team, the architecture was decided to be this handler concept, which did a few different things, right? It kind of decouples the, like the virtual kind of representation of the view from the platform implementation. And it gives us kind of a nice way to separate out, you know, different implementations of that representation. But the other kind of interesting thing is the way that it layers on. So there's this concept of, we have, still have today, core versus controls. And the idea with core is that, ideally that the handlers live in core. so that it doesn't really matter the mechanism that you're kind of using them to write your code to display your UI, but you always have this implementation of these handlers on the platform that you can represent a button with a native control button. And then the next step up is what we call the controls layer, which is kind of what... Jon (08:16.17) what gets you your binding, right? Your bindable properties and your XAML and your MVVM kind of approach to interacting with those handlers. Now, in a perfect world, everything would be kind of core handler. We didn't quite get there with some of the more complicated controls, like collection view is still in the controls layer, kind of. It's not a pure core abstraction. But the idea always was like, hey, MVVM, XAML, great, but maybe in the future we wanna make sure that we haven't painted ourselves into a corner and be able to do something different and not have data binding and all that stuff. So if we ever wanted to go MVU, we could. And there was an experiment, if people haven't heard of it ever, called Comet, that was mostly done by James Clancy, who used to be at Microsoft at the time and working on that. And Comet was more MVU style. It used the core handlers, but it added its own kind of how you program against those in its own way, all C-sharp based, all MVU kind of style, that kind of thing. Am I missing anything? Is that an OK explanation of kind of the architecture, do you think? Do you have any other commentary? Allan Ritchie (09:30.77) Yeah, no, that's a good way of explaining it. From the porting side of it though, I think what the real wins there is Xamarin.Forms didn't really have a, you know, everything was kind of a little bit different how things worked. So like fonts were registered different, which, you know, we'll talk about them a little bit more. Your hand, sorry, your renders were registered a little bit differently and they existed on kind of the head Jon (09:36.632) Yeah. Jon (09:48.098) Mm-hmm. Allan Ritchie (10:00.938) So you kind of had this code all over the place and it wasn't easily discoverable because you also didn't have that dependency injection filtering everything. And Xamarin forms did this like assembly scan, which was also slow because it scanned everything. So lo and behold, now because of that DI, first of all, you know your discovery point because you're like, oh, there's a button handler. I want to do it a little bit differently. And then you hop over to that. And now because of single projects, right? Jon (10:04.823) Yeah. Jon (10:11.384) Yeah. Jon (10:15.223) Yeah. Allan Ritchie (10:30.734) My Android, my iOS and those other platforms that we don't like to talk about are also in there right in one spot. So it's all discoverable, it's all easily shared or understood and you know what platforms are missing, right? Because it's just right there. So that was a huge, it's actually a bit bigger than people think because that stuff would be hard to find otherwise. Like you'd need to go looking for these attributes which no one ever registered in the same place, ever. Jon (10:44.642) Yeah. Jon (10:58.058) Yeah, so to back up a step too, cause I don't know if everybody listening might, understand some of the history of that there too. Yeah, like when there's a few different things that you kind of mentioned there, right? So let's unpack some of them. One of them being the fact that we're using more of like the builder pattern, right? That you're familiar with ASP.NET, other types of.NET projects, like it's pretty common to have this like, app host builder kind of thing. Allan Ritchie (11:16.45) Yep. Jon (11:24.882) Um, and, and so we have a version of some of that and you create your, your builder, you register your services, you register your fonts, you register all the different things, right? And like you said, that's the one kind of place that you know, to go to discover those things and how to do them. And. There's a few other benefits to that, like plugin authors kind of get an easier way to tap into some of the life cycle events and stuff, whereas in forms you would have to do some weird like init calls to plugins in random places and call different things. So this is kind of organized that a little bit better. it brings more consistency with other stuff too, right? You can reuse some of the things that you would maybe use with ASP.NET. Some of them are maybe not the best idea to do for performance reasons, but you can certainly use a lot of the different like logging things and configuration stuff and all that kind of thing. So there's the app builder kind of part of things. And when you're talking about registering like a custom font, for instance, Yeah, that used to be like, I think you mentioned an assembly level attribute that you would include in your code. And like you said, where does that go? Who knows wherever you wanna put it, it's C sharp. It doesn't really matter, right? So it was not super discoverable. And then we would actually have to go and scan at runtime for those attributes. And they were assembly level, so they weren't as slow to scan for. But they weren't fast either. And so there was a number of implications with like startup performance and stuff too. Same went for renderers and for dependency services. Allan Ritchie (12:59.314) Oh yeah, there was lots of scanning going on. And it, to be fair, it's not, you know, when you get into Android and all the support libraries, there's actually quite a few more assemblies to scan than it's a, it can get up to a few hundred. Jon (13:09.717) Yeah. Yeah, it takes a bit. I think back in the day, I remember talking about like, oh, could we do some tricks to kind of like block list some of the assemblies that we know aren't gonna have these attributes and stuff like that. And there was all sorts of performance optimizations that were now not necessary because we're just doing things a little bit smarter. So the... Allan Ritchie (13:33.194) now we'd have source generators to scan those things too. It's a shame. All these things we have now that would have would have fixed that. But anyhow. Jon (13:35.934) Yeah, that's true. That's true. Yeah. So the other part of that that's worth kind of breaking down, I think, is single project and what that means. What's your attempt at concisely explaining what single project is? Allan Ritchie (13:56.218) Funny thing is I've been doing, because I do a lot of libraries, I've been doing this single project stuff for quite a while or multi-targeted project or whatever the heck we want to call it. But it didn't really apply to a forms app, right? Like you couldn't do it at a forms level, right? You could try, but the compiler would get a little confused. Some of the Xamarin forms build tasks would get even more confused. So that wasn't there. But now... Jon (14:14.634) Yeah. Allan Ritchie (14:23.782) what those multi-targeted projects did was kind of again, focused me in one area. So my library, you know, we talked about doing bait and switch. I don't know in a previous episode where it was like. Jon (14:33.931) Yeah. Allan Ritchie (14:34.978) Here's my iOS library. Here's my Android library. Here's my Windows library. Here's the net standard. That's the bait. So the compiler would see all those methods there and then go, yeah, when the compile happens, we're going to pull the iOS version, right? And it would just kind of work magically with a trick. Jon (14:51.998) Yeah, it chose the right assembly for the platform from the NuGet package, you know, if you packaged it up correctly, right? And so your public API always had to be, you know, the bait and still exist in the switch, but like, you know, you could do whatever you wanted beyond that in the switch. Allan Ritchie (14:58.804) Right, but- Allan Ritchie (15:08.63) Exactly. So it was, it was really hard to, you had to package it up specially. You had to work with it specially, and you had to just kind of know that things were there. But if you wanted to take advantage of things like exposing maybe some of those APIs for Apple specific tasks or Android specific tasks, it was a lot harder, right? You didn't have those compiler switches that you could do. There was cheats, of course, but it just... Jon (15:25.924) Mm-hmm. Jon (15:35.786) Yeah, so the. Allan Ritchie (15:35.882) Now that it's all in one place, right? I can just say if Apple do this or if iOS do this, if else, if Android do this. Jon (15:42.09) Yeah, because the, the multi-targeting worked to an extent in Xamarin for just libraries, like you said. And I think like Claire Novotny was one of the ones that are made a nice helper library to kind of make that easier to do in your, your library projects. But yeah, like you said, it didn't really work in the app heads. And so back with Xamarin forms, you would have one CS project for every platform, basically for your app. Right? So you'd have an iOS one and Android one. And if you had other platforms, you'd have those too. Allan Ritchie (15:49.132) Right. Jon (16:11.774) And so the pattern for even for consuming things there was commonly like dependency service, right? And so you would create your public interface. It's kind of like doing your own little bait and switch in your app. You'd create your interface or class or whatever. I forget exactly what the requirements were. You'd register that, you know, as a dependency service with another attribute that we did. you know, stuff with, and then you'd have your platform specific implementations that would be, you know, what gets wired up at runtime and when, or not runtime, but when you build that app, I guess. There was probably a runtime component if we, yeah. And so, yeah. Allan Ritchie (16:45.938) No, it's runtime. Because if you were missing it, it would fail. And you wouldn't know it failed. You wouldn't know you were missing that dependency until you called it and it came back null. So that was another kind of bonus thing that was there. Jon (16:54.55) Yeah, that's true. Jon (17:00.554) And that was a lot of kind of ceremony for doing potentially something simple, right? Like you could have a dependency service that had like one line of code and each that was platform specific for the implementation basically. And, but you'd have to have, you know, your separate CS files across all your projects and you'd have to have your assembly attributes to register them all. So it was like just a lot of boilerplate kind of cruft to do something very simple, which now with multi-targeting, or sorry, single project. When we talk about a single project, I think people get sometimes confused because single project was like the term that we coined for this idea that one, we would use multi-targeting and two, we would add some kind of helpful. stuff on top of that concept to help you out with building your app more easily for all the different platforms. And we'll talk more about what some of those are. A lot of it's to do with like resources and stuff. But for single project is really just multiple TFMs in a single project. And those multiple TFMs with target platform frameworks would be like net8.0-iOS, net8.0-android, et cetera. And so now for something like dependency service, I think you already mentioned, like you can have your compiler directive. So you could say, you know, if Android do this, else, you know, if iOS do this, else event, you know, whatever, however you wanted to arrange it. And so for like a simple dependency service that might've been, you know, one line of code for each platform, like you can now do that just in line in your C-sharp code in your single project. And the multi-targeting is going to declare the right compiler directives and make that toggle happen for you. Right? So it's a much more concise way of achieving some of what we used to do with a bunch of ceremony. Allan Ritchie (18:50.718) I think the other thing people don't realize is because it's single project, there's actually some real cool ways in order to save compile time. So if you're in a big Xamarin project, it wasn't uncommon that you'd have several different project references or... And they would be compiling net standard Xamarin iOS mono Android, right? And it was really kind of crazy because you'd have to figure out, okay, well, I only want to compile Android. I don't need everything compiling iOS as well. So I'm only working on Android and sure. It sounds easy because you just say, okay, well, you know, unload my iOS project, but you'd still have all your other libraries, still compiling the iOS version of the library. So you'd be going through this whole ceremony. Jon (19:20.279) Yeah. Jon (19:37.131) Mm-hmm. Allan Ritchie (19:37.14) Now you can just say, look, first of all, we don't even need to compile net standard, like the bait. We don't need to compile the net eight. Jon (19:41.878) Right, yeah, so that's one target gone. Allan Ritchie (19:45.694) Right. You're just compiling literally the platforms. So you don't have to even work on an abstraction to the, to the deepest sense, right? To the common denominator. You can literally say, this is the way Apple does it. This is the way Android does it, live with it, compile those two platforms or compile one of them. And the out of the gate experience for that really revs up the inner dev loop, right? I'm always, I don't usually compile for all the platforms at one time. I'm always commenting out one of them. Jon (20:09.355) Yeah. Allan Ritchie (20:15.648) saying just give me Android that's all I'm working on right now always Android gotta work on there first because that's where things are gonna break Jon (20:19.434) Yeah. And by default, like visual studio and stuff will, will kind of, you know, we had a lot of conversation about how this should work too. So like one of the interesting things was like multi-targeting was a thing before Maui started using it. But when we started using it, I know there's a lot of people on other teams internally that were like, that's not really what we intended this to be used for. We thought more like, you know, net. 7.0 and net 8.0 for like a library author, you know, that wasn't like pivoting based on the platform. But, you know, kind of too late when the box has been opened, we started using it. And so that did nicely kind of force the issue of, okay, well, how do we make this work better, you know, in Visual Studio and stuff, right? So like, if you go to hit debug and you have like the, you know, a Android emulator selected in Visual Studio, it's going to compile that project that you're debugging only for Android at that moment. But if I go right click on the project in the solution explorer and I hit build. it's going to build all the different platforms. And that's, you know, kind of a really conscious choice for trying to make things reasonable because it's, it's also kind of jarring if like you only ever compiled Android and then you go to switch over or something and also and everything breaks, but you think you've been building successfully up until that point. Um, but it's a little bit of give and take the other thing is, um, visual studio, the way that they do the project walking is like. really complicated from a performance perspective. And so if you have a bunch of referenced projects that are also multi-targeting, like they don't always know how to tame that down so that it only picks Android the whole tree down. And it's a really complicated issue that like, you know, when we started talking to that team, I was just like, oh, I didn't realize how complex this was that this would actually be hard to do, but. Allan Ritchie (22:08.944) Yeah. Jon (22:18.322) generally like, you know, you're not working with a ton of different projects like that. And so compiling dev loop wise is pretty good. Allan Ritchie (22:25.838) Well, like I said, this was this is one of the savings because a lot of these projects do have many libraries, right? So one of the things I usually have customers doing is if you're using a third party library, bring it in, fork it right. So you can either a fix it because a lot of this stuff has disappeared. Right. If you know, a lot of James's plugins, James Montemagno had a lot. He's deprecated them in favor of essentials. Jon (22:53.814) Mm-hmm. Allan Ritchie (22:54.982) I had a lot, people still use that stupid user dialogues thing. I kind of, I, it's on life support. I kind of just breathe on it when somebody asks me. Um, but you had all these in it calls and Jon (22:59.092) Oh yeah. Allan Ritchie (23:07.618) The thing is, is that people would start to bring those in just in case, you know, I walked away, which is good. So you still had, you have a lot of these people that have brought these libraries in and they compile it with their project, which is good. It's smart business continuity effect. It's just that many more things to compile and inject in your app. Jon (23:12.555) Yeah. Allan Ritchie (23:26.85) Right. So that was, that's one of the key things that I've seen. So if we go back to kind of the core of this was migrating from forums was a lot of those third parties, you know, they, they used a lot of libraries that are just gone. So like, I don't know, I can't even think of all James top activity, uh, user dialogues, uh, spilling, uh, zebra crossing. Jon (23:34.637) Yeah. Jon (23:44.845) Yeah. Jon (23:50.578) Yeah. So, and like a lot of those, yeah. So I think, you know, there's a few categories that many of those fall into. Like one of them is, like you said, like maybe there is a better way to do that. Now, anyway, like the, the top activity one, you know, was early days, I think even before we made Xamarin essentials. And so now Xamarin essentials has also come across and is now baked into Maui. Um, like it's, you just get it in your Maui apps. It's not a separate, uh, new get. I mean, it kind of is, but it's not technically. Um, and so, you know, some of those ones are, are just like, there's already a way to do this, like just use the new way, but it is a, if you're migrating your app, obviously that's still a change that you probably have to make. Um, hope, you know, those kinds of situations are probably not that as hard to do if you're just trying to get the current activity, you know, like there's a, there's a better way to do that now. Um, and, and then there's, there's things like, you know, zebra crossing or, um, Allan Ritchie (24:40.185) Yep. Jon (24:45.494) Like in a billing, you know, James has made work for, for Maui. It works. I'm using that in my pool app too. So like, there are definitely some that you don't know, uh, without looking, maybe a new get to see that they've added those target frameworks for, for net eight or net seven or net six even. Um, so some of them just have updated, which is nice. Some of them, you know, haven't. And like we had a number. of plugins that were kind of the most commonly sought out by, you know, some of our customers who are doing migrations. You know, it's zebra crossing was one of them. Um, trying to think of some of the others that there were, there were, Oh, FF image loading, right? That was another one that people use like crazy. So we did take some time. I took some time to port some of those over myself. Like there is a Maui FF image loading that I'm, you know, it works like, you know, it's, it's maybe fine to bring your app over. Um, Allan Ritchie (25:24.65) Yeah. Jon (25:38.674) Some of them were kind of saying like, yeah, do the migration so that you can get there. But, you know, maybe consider long-term that like that dependency isn't really something you want to be using. Um, you might want to pivot to something else. Allan Ritchie (25:50.405) What's interesting is that we call those plugins, right? Jon (25:53.215) Yeah. Allan Ritchie (25:53.462) And this is the thing I try and separate for customers because when we talk about third party dependencies, a lot of those ones that aren't Maui specific or Xamarin form specific, which a lot of them weren't right. Like user dialogues wasn't dependent on Maui in app billing isn't Maui specific. Zebra crossing had a control. Right. But for the most part, it was its own thing as well. It lived and breathed in the platform. It didn't matter about Xamarin forms. So those are what I consider the plugins. Right. Jon (26:06.699) Right. Right. Jon (26:15.135) Yep. Allan Ritchie (26:23.056) would become that I've seen problematic for a lot of authors or a lot of people porting is stuff like the UI elements right so like you said FF image loading that's a popular one because it really does a lot of things that this the out of box image doesn't do I think when you ask me like why are people using this because you have cache and I was like authenticated images right I think that was the one that immediately jumped to my head because a lot of people you know Jon (26:30.944) Yeah. Jon (26:35.022) Mm-hmm. Allan Ritchie (26:53.096) your image without being authenticated first to say I'm spying on you John I'm stealing your image I don't know why but I am Jon (26:54.451) Yeah. Jon (27:00.862) Yeah. Yeah, I know that makes sense. I mean, there's definitely corner cases that we don't address in the box. And, you know, there are plugins that people were using. It's. Yeah, I think there's still going to be a gap with some of them, obviously, especially if we, if, you know, I kind of make the statement too, right? Like we have FF image loading, but you know, is it super well supported? I mean, like I did a port, I'm not the original author of it. And like, it's not something that I'm going and, you know, making sure I update and check all the bugs and stuff. It's like, yeah, there's some base level that works. Um, it's open source. You can go fork it yourself and make it work for your purposes. If it doesn't. Um, Allan Ritchie (27:37.858) I think somebody actually took your fork, forked your stuff, fixed your, fixed some bugs that were standing in the original library and released it. Cause you didn't release it, did you? You didn't release it to NuGet. I don't think you did. Jon (27:40.642) They forked the fork. Great. Jon (27:47.822) Uh, I thought maybe not, maybe not. Yeah. I'm, you know, it's always hesitant because like on some level, I, when I do these things too, like that's actually, that's the pattern that I would like to see happen is somebody go pick it up and run with it, but I also recognize that sometimes like, you know, doing the initial port and I did spend the time to try and like single project stuff and make things just more in the Maui, you know, pattern of it. Um, and, and then. Yeah, doing that, that first step of work is probably the hardest for someone who's not familiar with it. And so it's like, okay, if I do that, then yeah, at least it's at that level. If somebody else wants to pick it up and run with it, please, you know, great. Do it. Um, so yeah, that's cool. Allan Ritchie (28:30.806) And so I think that was that was the thing is moving some of those third party controls. The plugins seemed I don't think there's many left that haven't moved. The controls were I think were almost there. A lot of people like that rainbow. Was that Devrain both debug rainbows or whatever it was? I never used it. Jon (28:40.256) Yeah. Jon (28:47.402) Oh, yeah, but there's been like a few versions of that already. Like somebody, I think, I don't know if it was Tim Miller or somebody else, like figured, like made a very concise, like handler, uh, property mapper or something that like did that just with a few lines of code. Like that was another thing with handlers is. Renders were always hard to customize beyond what was like, if it wasn't your code for the hand or the renderer. Allan Ritchie (29:06.359) Okay. Jon (29:15.422) it wasn't easy to augment that without creating a new render yourself. And so with handlers now, yeah, there's like a property mapper. Um, and, and so you can kind of add your own mapper that will get executed in, in kind of the right order of things. And so you could, if, if your goal is for instance, to like, you know, put an underline on a label native on the native label for whatever reason, maybe bad example, but whatever, um, Allan Ritchie (29:20.638) Yeah, and now you can just kind of tack it on. Jon (29:43.726) you know, that's pretty easy to do with, with just changing up the, the property or the, the property mapper on the handler, um, and customizing it yourself. So that was another motivation for that architecture was like, we, I think we saw people doing these common things were like the out of the box render was 99% of the way there. I just wanted to tweak it a little bit. And so this in theory and in practice from what I've seen anyway, it helps achieve that more easily. Allan Ritchie (30:10.582) It is. It's a big thing. I mean, I had one design where they wanted. I forget what it's called. They wanted the font kind of spaced out a little bit more. What's that? I forget what that's called. Any. No, it was like the letter spacing. And I was like, what is this? Like, why is this a thing? And they really wanted it for the design. And I was like, OK, we're going to split hairs on this. All right. Jon (30:19.422) Right. Uh, yeah. Font spacing. I don't know. Yeah, there's yeah, I know. Yeah. Allan Ritchie (30:35.934) And Xamarin forms didn't have it at the time. So we had to write a whole custom renderer for a label to do this letter spacing. Now it's out of the box. Thank God. But if, if I had a handler back then, you know, it would have been a lot easier cause it would have just been kerning. Is that it? Just this kind of popped into my head there. Um, I'll take a chance. I probably wrong, but that word jumps into my head for some reason. Jon (30:40.671) Mm-hmm. Jon (30:51.926) Yeah, that's what I was thinking, but I'm not sure. I didn't wanna be wrong. Allan Ritchie (31:02.186) Um, so what we had to do that, if we had been able to do that with a handler, it was basically one property in Android. It was one property in iOS and that was it. Right. We would have been done and all the labels would have had it that, that value without any work. Now the frank answer here is the designer was a pain in the ass, but we still needed the feature. The designer won that call because it was their brand. Okay, fine. But now it's out of the box. It's super easy to do anyways. Jon (31:24.874) Yeah, exactly. Allan Ritchie (31:32.574) know, bingo bongo and on we go. Jon (31:34.238) Yeah. And so, and talking about handlers and renderers, like that, from a migration perspective, um, you know, I think people are often kind of scared of, of that area. So like, I know I found with my app when I was migrating it, you know, a couple of things, one, if I truly looked at my custom renderer, often half of them, I would say, I could kind of say, I don't need that to do what I need to do anymore. Allan Ritchie (32:03.054) Yeah, it's out of the box. Jon (32:03.274) There were other ways to either was out of the box or maybe there was like a behavior I could use from a plugin like Community Toolkit or maybe I could write my own effect or something or behavior. So that was an option or like I could write a property mapper addition and effect the thing that I wanted to. But for the other ones that were substantial enough that I did want to recreate it, they were pretty easy. We've since got some docs to kind of guide you through, like, where do I put these blocks of code in my handler? And what's the kind of match up and difference? So it's really not that hard to do if you actually have to do it. Allan Ritchie (32:48.21) The only handler I still see a lot today is one thing, and I know why it doesn't exist out of the box, is the entry handler. or more specifically the no borders, but it's because that involves really mutating the native controls, right? So that's really something that you have to decide how you want to do it. I know a lot of people complain about it, but remember that the first is to look native and when you want to change it, that's when you break out. So I get why you guys don't do it out of the box, but a lot of customers don't tend to understand that. And it's like, well, it's good reasons for it. Jon (33:00.815) Oh yeah. Jon (33:04.672) Yeah. Jon (33:12.695) Yeah. Jon (33:22.19) Yeah. And I think that one too, like I was just kind of going to go look at my, my pool app code. I think for those, I started getting away with behaviors instead of handlers. Yeah. Like I've got a, an entry customization behavior that I made and you know, behavior is a little bit different than a, than a handler because you're not, you're not like changing the. Allan Ritchie (33:36.11) which might be the case. Jon (33:50.766) properties per se, like the default properties with the behavior, right? So your behavior you create and you can have it be attached to the virtual view, the cross-platform control. And when it is attached, you get an instance of the thing it's attached to. So I get the actual entry and I can say, okay, like. wire up when that entry loads and then when that entry is loaded, I can start to customize it and I get access to the native view at that point, right? So when my behavior attaches and it's, you know, the view has been nicely loaded up, I know that for sure, I can start to say like, okay, change the border, change, because I do that in mine. I get rid of the border, I do all that. So like that's one of the areas I think if you've got custom renders, you might not even have to do Jon (34:42.102) you know, like I said, property mapper, et cetera. So like it's worth looking at it twice before you just ported over. Allan Ritchie (34:48.854) I think that's one of the ones that just comes across because it works. But that is the one I usually see left behind. So it's just interesting how people have solved the problems. The other thing I tend to see a lot and thankfully this isn't really a problem because they pretty much port one to one is converters. If you've got 10,000 converters in your app, you probably want to reconsider what you're doing. Just saying, just saying, just saying. Jon (34:52.683) Yeah. Jon (34:59.501) Yeah. Jon (35:08.811) Yeah. Jon (35:15.318) I don't have 10,000 yet. Like 9,000 or so is probably fine then, right? Allan Ritchie (35:22.52) Yeah, unless you want your consultant kind of going, guys, what are we doing here? Can we look at doing this simpler? Maybe? Hmm? Jon (35:30.974) Good thing my consultant is very amenable to my own thoughts and ideas. Allan Ritchie (35:38.688) But the converters come across one to one. So at least there's nothing there. So we've talked about do we talk about images, images and fonts are pretty much the same thing. Jon (35:41.065) Yeah. Jon (35:45.278) No, I was going to say resources is probably another good one to dive into, right? So. Allan Ritchie (35:50.851) Images, app icon and splash screen are all pretty much the same. Yeah, they're pretty much the same thing. Jon (35:52.826) Yeah, all these things. They are. So when I mentioned before a single project was kind of like the term that we use to describe a Maui app that was multi-targeted, but plus more, right? It's like that's what single project means to us as the Maui team. And the plus more part is a number of things, and mostly around different kinds of resources, though. So in Xamarin Forms, If I wanted to have an image to throw into an image view, I would have to make that image go into every different application head for each platform, right? So iOS, I would put the image there. And on iOS, they have different pixel densities for images. And so their convention is kind of like... You have your 100 by 100 image is your, I think implicitly it would be like my image at 1x.png, right? Allan Ritchie (36:50.855) You're going to the original old school. They have assets that do that and still name them that, but I know where you're going here. Jon (36:53.131) Yeah. Yeah, yeah. And then you would create a 200 by 200 and a 300 by 300. And the idea there is that you have multiple copies of the image so that iOS can display the right density because we started with iPhones that were not the same pixel density when they made the retina screens or higher pixel density. And that's kind of been going up and up. And Android had a similar concept too or has a similar concept. It is worse because it's more images, right? There's like, you know, drawables of like, uh, there was LDPI. I don't even know if that's like in use anymore, right? Low DPI, then medium DPI, high DPI, uh, extra high DPI, extra, and then the three X. Yeah. So like you, you would end up with all of these images, right? And so that was a pain, like depending on how you, you built your app. If I, Allan Ritchie (37:23.985) Oh, Antrite is worse. Way worse. Allan Ritchie (37:33.21) Hehehehe Allan Ritchie (37:39.19) Extra extra high extra extra. It's crazy Jon (37:51.966) started with like a PNG, like hopefully I had one that was at least the resolution of the highest DPI I needed so that I could downscale, which isn't great either in some cases. Allan Ritchie (38:03.207) And a good aspect ratio too, right? Jon (38:04.99) Right, right. Yeah, yeah, exactly. Cause then you're getting into weird like fractional pixels as you downscale it, right? So what I think some people started doing eventually and I kind of looked at as well was like, okay, if I have a vector, I can more easily generate that in the various sizes I needed, but it was still a task. And I think there was a number of like, there was an IDE plugin, I think for VS Mac and you had an app. Yeah, so there's like a bunch of ways to generate these. Allan Ritchie (38:29.846) I had an app. I had an app, you drag it and it would give you two big folders full of the Android icons and you still had to go and copy those over into each individual folder. It was a pain. Jon (38:36.96) Right. Yeah. So like it got to the point where I've, I remember like adding a new image to my app. I was just like, I don't want to do it. Like, can I avoid using any more images? Cause it's just, it's extra busy work. So. Allan Ritchie (38:50.938) Hehehe Allan Ritchie (38:55.151) Yeah. Jon (38:56.726) I, at some point when I got frustrated with that, as you know, I think most developers do it's like, well, what can I build to help make this easier? Right. And then also classic developer move. It's like that I want to build the thing so that I have to spend less time on doing the thing. And then you ended up spending like, you know, exponentially more time building the thing that's going to save you that time instead of just doing it. Um, but you know, that's what we do. Right. So I had built a, a new get package. Allan Ritchie (39:17.424) Hehehe Jon (39:25.046) with a bunch of MSBuild tasks and properties and targets and stuff called resize-itizer. I think I was, I made one version that was kind of dumb and then I made another one and called it like resize-itizer NT or something silly because of, you know, the funny naming at the time, like where all of our names of Xamarin things were like Miguel's like, oh, we're gonna call this the whatever, you know, 2000. So we just came up with as ridiculous of names as we could for things, it was fun. Allan Ritchie (39:39.982) Hehehe Jon (39:55.062) Did you ever use that plugin that I made? Allan Ritchie (39:58.174) I didn't because it was right near the end of Xamarin Forms life. I think that's when it started. And then you were like, I don't know what I'm going to do with this. I might go to Maui. It might not. There was a lot of talk. It, you weren't sure at the time. Fast forward. And now I use it, whether I was going to or not, because it's out of the box. Jon (40:02.347) Yeah. Jon (40:10.015) Yeah. Yeah. Jon (40:18.102) Yeah, now it's kind of in Maui. Now, you know, other kind of classic pattern and my original code that was probably, you know, not the best code, you know, got a little bit of a makeover too. And Matthew Leibowitz on my team, you know, prolific author of many things, including Skia Sharp. um, you know, helped me, uh, turn it into a much nicer thing and more features and more support and stuff. And so, you know, today, like it, so you basically, you give it a image, right? You give it a SVG, hopefully you can give it a PNG too. Um, but factors are nicer and it will add build time. Create the different density, you know, resolution copies of all the images for the platforms that you're targeting. And so you put that vector in a special place and then it gets included by default. So in the resources, there's an images folder under there and all of those by default are included in this treatment. And it'll produce all the copies of those images for all the different right platform folders and everything for you. So you don't even have to think about it anymore, right? It just does it. Allan Ritchie (41:25.582) You suffered for our laziness. Jon (41:27.818) Yeah, and it's not perfect either in the sense that like, you know, it's, it's skia sharp doing vectors with the library that does that. So like, you know, maybe not every vector you throw at it is going to be super supported. It handles a pretty good amount of cases though, from, from what we've seen. And the other thing that's really, there's two things that are kind of tricky that people don't usually necessarily like understand. One of which is, you have an SVG going in, but it's turned into a PNG going out right in the app. And so in your code, you actually have to reference the PNG, not the SVG. And so people sometimes make that mistake. And probably, you know, we could be clearer about it or try and detect it in your XAML and give you a warning or something. Allan Ritchie (42:02.138) Yep. Allan Ritchie (42:17.03) Well, here's the thing though. Here's the thing about that. I wish people would understand the platforms they're working with, right? Because SVG is not native to Android or iOS. It's not, so. Jon (42:24.791) Yeah. Jon (42:28.478) Right. I think iOS does technically support SVGs in more recent versions. Allan Ritchie (42:37.507) Like their icons and stuff. Yes, because they eat, they'll take a vectorized PDF, right? So the thing that you're doing for resize the tizer. Jon (42:42.998) There's that, but there is, there is SVG now. I learned that recently, but I think it's only like newer iOS versions. So like, it's not all the way back to what we support in terms of targeting. In any case, like Android still does not to my knowledge. I mean, they have like Android vector drawables and there's a tool in Android studio that can convert SVGs into that format, which is just like their own. Allan Ritchie (42:48.621) No way. Okay. Allan Ritchie (42:55.489) Okay, so. Jon (43:08.666) limited subset of XML and I actually ported their code which is open source for converting vectors thinking maybe this is how we could do it you know natively and it was horrible like it doesn't it doesn't support very much at all and you end up like throwing any moderately complicated vector at it it's like nah I don't know what to do um so that wasn't really a Allan Ritchie (43:09.222) Shaky. Allan Ritchie (43:32.25) That doesn't sound like an entrate at all. Not at all. Jon (43:35.718) And there's libraries out there to do SVGs at runtime with Android. And I think does FF image loading do? I don't even remember. I, and I ported the thing. I think it does. Right. So there's ways to do it. You can do it with skia shark with the skia shark view, but we don't support rendering vectors at runtime. Allan Ritchie (43:45.11) Yes it does. Jon (43:55.346) natively in Maui itself. It's just, it's such a, it's a bigger problem than most people understand. Like SVG is pretty much its own web browser, is kind of the extent of it. Allan Ritchie (44:05.422) Yep. Well, if you look at it, it's basically markup. It is markup. Jon (44:09.662) Yeah, and more than markup, like there's like JavaScripty kind of things and technically in some of the specs too for SVGs. So it's, it's complicated. So yeah, but the images get produced. We added a couple other things like app icon because on the Android you can compose, you know, a foreground image and a background image. Like I think we talked about on one of the last episodes with, uh, Allan Ritchie (44:17.562) Hmm. Jon (44:34.85) their adaptive icons. So the idea being like your background is separate because the user might choose round or a squircle. Remember the squircle? It's like a rounded rectangle. So they will dynamically compose your foreground onto the background. And so we support those being generated from your two images, which is kind of cool. Allan Ritchie (44:36.77) Yeah, that's the one. Allan Ritchie (44:46.138) That one I've never heard of. All right, a squirkle. Learned a new word today. Jon (45:01.098) And then iOS will kind of collapse that for you. But so AppIcon was intentionally like its own special thing because of that adaptive icon support. And then splash screens are kind of similar. We don't give you a lot of leeway in what you do with it, but you can generate your splash screen through the Maui single project resources where you basically can say, hey, here's the background color of the splash screen and here's an icon to throw in the center of it. And yeah, we do that for you. Allan Ritchie (45:30.39) Yeah, that one you got to kind of figure out the sizing though. I find splash screens are a little bit, you have to have a little bit more knowledge of what you're giving it in terms of the vector versus the app icon and just images in general, right? Cause you don't have a lot of control over that splash screen sizing. Jon (45:33.207) Yeah. Jon (45:38.84) Yeah. Jon (45:45.79) Yeah. And so if you're talking about migrating over again from forms, if you're bringing your project over and you're trying to collapse your forms project from multiple app heads into one with resources, you can do two things, right? You could copy your platform resources over. There is a platform's folder in the Maui project, and then there's like an iOS folder, an Android folder, et cetera. And those you can just copy and leave. And that will be like the default. you know, how you kind of have it in your app head today. Those are all platform specific. So now the resources, Android resources folder is like the Android resources folder. So you can just copy those over. But if you wanna go back and kind of do the little bit extra step of migrating into a true single project for Maui, you know, you can get your source images and throw them in the shared resource image folder. And then the other thing that people don't usually get with when they do that is, okay, well, here's the problem. If I have a vector, your vector might describe itself as like what its canvas area is or like what its kind of overall container size dimensions are, right? But it might say, hey, I'm a 10 by 10 or let's use a bigger size. Let's call it 30 by 30. And it's a vector though. It can scale up to whatever size you want, right? But the problem is like we don't really know based on that size if that's the size you truly want to use it in your app. And so we can't just say like by default we do just say give me the SVG size like the box size and we'll use that as the number to like multiply it by. So for a you know at 2x at yeah at 2x image for ios we would make it 60 by 60 and then 90 by 90 for the 3x. Well but what if in your code you are specifying that image size as 50 by 50? Because you know it's a vector we can scale it up like it's fine. But we don't know that. So there is this other attribute for the maui images called Jon (47:55.002) And that one's kind of hard to understand. And I've thought a lot about how do you make it so that like it's, it's kind of self describing or understandable. And I haven't come up with a good answer, but the thing to do there for anyone listening, if you're migrating your stuff over, if you have an image view in your XAML and you want that image view to show an image that is 50 by 50, set your base size attribute in your CS project to 50 by 50. And that is what we infer for kind of doing the calculations for all the different densities. And it doesn't really matter the source size of your image for a vector anyway. So if your vector is 30 by 30, but you say base size is 50 by 50. we'll do a 50 by 50, a 100 by 100 and a 150 by 150 for iOS. Like that's the way the math works out, right? So I see people not understanding that, fairly often still, and I think it's worth pointing out, there is docs and stuff on it, but like you have to understand that bit. Allan Ritchie (48:57.17) I think the funny thing is you don't usually see a lot of this stuff yet in the ports. You see it in more than net new stuff or where people are doing net new images, right? So they're adding features to their app. So I'd be surprised. There's obviously going to be more issues of that in the future where they don't understand it. So, but in terms of porting, you don't, you don't generally tend to get a lot of that yet. I think it's coming app icon. They do app icons. People are porting. Jon (49:02.795) Yeah. Jon (49:08.021) Yeah. Jon (49:25.279) Yeah. Allan Ritchie (49:26.306) Fonts, obviously they're porting. Images, it depends still. Sometimes it's just a copy paste job right now. Jon (49:35.466) Yeah, and fonts were another kind of fun one to do. If you remember in forms, like you would, how did that go? You would usually, like every platform you kind of had to just describe the font differently, right? So I think like you would end up making often, or I would anyway, like a resource that was a dynamic resource that had like a different. Allan Ritchie (49:48.026) different syntax. Yeah. Jon (49:59.686) syntax for each platform and then I could refer to that resource as the font name and it would get substituted with the right thing for the right platform. Allan Ritchie (50:06.346) Yeah, because they had different naming conventions based on iOS and Android. And you guys weren't quite factoring for that yet. And now it just, it's out of box, right? Jon (50:10.72) Yeah. Jon (50:16.81) Yeah, now it mostly just works. I'm trying to remember offhand what the default font registration looks like, but I think it's like, you just give it the file name and it goes, right? And the alias. Allan Ritchie (50:27.01) You give it a file name and it's you have to specify it as a mount Maui font and then you call it whatever you want. And then you say this is a font family I want you go figure it out, which is that's awesome. That's another big time saver. Jon (50:32.971) Yeah. Jon (50:39.05) Yeah, it's been nice. That was another area that I felt pretty strongly that we needed to do a good job on to make easier to use. So. Allan Ritchie (50:47.65) Now thankfully a lot of people tend to specify their fonts in the global styles anyways, usually, usually. So that porting effort is usually not as hard because it's already there. Like the style just carries over. So let's talk about some of the paper cuts. This is the term I've used for things that people are kind of... Jon (50:54.966) Yeah. Jon (51:02.078) Yeah. Jon (51:07.) Yeah. Allan Ritchie (51:11.57) off the cuff. Now David covered a lot of these recently. He had a whole through well he did it on the community stand up right. Yeah we'll definitely link to that but I think he was missing one of the big ones. I think this is one of the ones I've told you about was the frame versus the border. The frame didn't quite make it over from Xamarin.Forms so it's kind of in I don't know where it is in Net8 because I just don't use it. I use border. Jon (51:17.198) That's right, yeah, we should link to that. Jon (51:29.239) Yeah. Allan Ritchie (51:37.126) The border is a bit richer now anyways, but if you're using frame, you're going to have measurement issues. That's just because border is the new way to do it. Just switch. It's painless. Jon (51:37.236) Yeah. Jon (51:46.686) Yeah, so we've done some bug fixes and stuff. It's like you recognize that people are trying to do this efficiently, right? And so like, yeah, maybe you have a bunch of frames. The challenge for us was that frame for Android always mapped to like their card view or whatever, I think, which had like some implicit styling defaults and things on Android. And then we tried to kind of emulate that on the other platforms. And so like... the native controls and use cause a lot of problems with like, yeah, the layout measuring stuff and everything. And so while there's been attempts to do bug fixes there and stuff, it's just, it's not as clean of a path and using a border is also much more consistent in how it looks and feels between platforms too. Like you can achieve the same like shadow around, you know, the frame kind of border container with, with a border now. that you could with the frame, but it's just a lot more compatible with everything else. So yeah, like don't, if you can help it, just replace all your frames with border. Allan Ritchie (52:53.998) That's that's one of the ones I tell people to do right away. Another one that I see common people some of the easier pages and I'm guilty of this as well. They tend to use stack layouts in a lot of places. Stack layouts are good. You know as long as. Jon (52:56.984) Yeah. Jon (53:05.985) Mm-hmm. Allan Ritchie (53:10.466) As long as they're kind of not changing sizes all the time. So I've seen ones where, you know, if you put a tap gesture, for example, on a, on a stat on a stack layout, right. And that stack layer resizes. Sometimes that touch area is either collapsed on you and you could say it's a bug, but really kind of stuff like that happens on the native platforms. Anyways, it's like it, you have to tell it. Jon (53:24.545) Mmm, yeah. Jon (53:32.142) Mm-hmm. Allan Ritchie (53:34.354) redraw it. Don't just remeasure it. Redraw the whole damn thing because it's the tab gesture is now down here, but your stack layout is now registered half of that. So it's weird how they do it. It's based on measurements, but that's another one. I'm like, don't, don't put it on, don't put your gestures on a dynamically sized thing because it's not good. There's going to be those issues, right? Just. Jon (53:56.703) Yeah, yeah. Allan Ritchie (53:58.978) Pick your poison, right? I use grids everywhere. Maybe that's not the right answer, but I'm also not a UI fanatic, but I use grids. Grids don't give you problems. Jon (54:06.75) Yeah, I tend to as well. I mean, I do use stack layouts in places. Like the other switch has been, you know, we used to have one stack layout and then you would do like horizontal and vertical as the property of it. And that's still there. I think probably the code path is fine if you've got it set statically to like one or the other. But I tend to prefer replacing it with like the actual control. Like if I'm doing horizontal, I will use horizontal stack layout. Allan Ritchie (54:34.744) Yep. Jon (54:36.766) And yeah, like I said, I don't think that, like I think if you have it in your code as always, horizontal for instance, like it's the initial state, it's the initial value of that bindable property. So it shouldn't really be a problem with performance either way. But yeah, I mean, if you're doing something like data binding that value, like that's probably not. Allan Ritchie (54:37.19) Is there a performance benefit to that? Allan Ritchie (54:54.084) Okay. Jon (55:01.122) It's probably not great UX design anyway, but you know. So yeah, swap them out for the main ones, I think is probably the safe thing to do regardless. Allan Ritchie (55:12.25) What other paper cuts am I seeing? Now I'm having a braid fart. Jon (55:15.882) Got to change all the namespaces and stuff in XAML. Now there is an upgrade assistant that we will link to it. I mean, I'm honestly, when I was porting pool math over, I didn't use it because it wasn't very mature at the time. I think it's improved since I haven't, to be honest, really used it myself a lot. So there's probably still gaps and it's, you know, one of those things that maybe it gets you started, but... Allan Ritchie (55:21.725) That's a good one to talk about. Jon (55:45.586) you probably want to understand the process. Allan Ritchie (55:47.77) I got a bit of a spicy take on it. Now it's not to hate on it. I don't hate on any technology. It's just, you know, you love it or hate it or it just doesn't do quite what you need. Now what I've been suggesting to my customers is it does a lot of magic. So it tries to do everything and then the customers don't end up knowing the state they're in and they really, they're just left with this gash of errors, right? And it's really hard to understand where to start. Jon (55:57.485) Mm-hmm. Jon (56:07.693) Yeah. Allan Ritchie (56:15.478) Right. Is one thing going to take care of all these issues? Is it a couple of fixes? You don't know. Right. And it could be a bit overwhelming. So the general way that I've had people starting, and this is how I've done it myself, I started a net new Maui app and I start bringing in a first, I start with the dependencies. What dependencies do I need to replace the ones that I have? Right. Can I replace these out? I start getting them all wired up in DI. Now I move to the services and the view models. Jon (56:21.591) Yeah. Jon (56:36.235) Mm-hmm. Jon (56:44.878) Mm-hmm. Allan Ritchie (56:45.302) And then I start bringing page by page over. Right. And it's very methodical because you know exactly where you're at. Right. So you might be able to get a certain portion of your app running so you can keep moving forward and the teams might, you know, chew away at some of the little, you know, maybe there's certain pages that's like, it works, but you know what, there's certain alignment. There's a frame. Jon (56:52.299) Yeah. Jon (57:03.914) Yeah, but maybe your handler isn't come. Yeah. Allan Ritchie (57:07.854) there's a frame that's not aligning stuff. So they're going to go in and change it to a border. And some of those things are even searching replace, like changing that. You mentioned the namespace that's you can sweep that. I have a script that does it in one shot. It takes like 30 seconds. If there's like hundreds of pages, boom, done. That's even a long time. It's like three seconds, right? You take those over. It's nothing, right? So that's minor. Um, but really if, if you've got an app of any size, Jon (57:16.108) Yep. Jon (57:26.573) Yeah. Allan Ritchie (57:34.51) You know, it's nice to shove it through the upgrade assistant, but I really that that's a good learning lesson. I wouldn't take that as a product to move over. Do it methodically on your own. So you understand what's moving and why it'll help you going forward. You're not just left with this kind of. Jon (57:40.674) Mm-hmm. Allan Ritchie (57:52.13) You know, maybe it's 70% of the way there. Maybe it's 80%, but you don't know that, right? You could have one change in there that's breaking and causing like 200 errors and it's one fix, but you don't know. Jon (57:52.141) Yeah. Jon (58:03.382) Yeah, especially with like a knit calls on plugins and stuff and stuff like that. Right. Like that that's, and I think when you do that process too, like start without things like custom renders start maybe without like, yeah, know your dependencies and kind of figure that out. But like, if, if you're registering, you know, a bunch of stuff, like maybe it's wise to like not. trying to introduce that, like comment some stuff out. Well, you kind of get the main thing up and running so that you know that at least like, you're not crashing on startup, right? Allan Ritchie (58:35.43) Do it without the magic is what I say. Because if you call it magic, it means you don't truly know what it's doing for you. And I think that that's where a lot of things start to fall through the gaps. Jon (58:37.314) Yeah. Jon (58:47.946) Yeah, well that makes sense. Well, I think we're approaching a good amount of time here spent on migrations. Maybe we'll have to do a follow-up episode on it too if there's any questions or anything. If you have questions about migration, you think there's good topics to kind of dig into farther that we missed, be sure to reach out to us. You can hit us up on our website, gonemobile.io in a number of ways, show at gonemobile.io for email. And I always have to ask if you like the podcast, if you want to see more, it always helps us if you subscribe on your favorite podcast player. It helps us even more if you leave us a nice review. Yeah, anything else? We missed you, Alan. Allan Ritchie (59:28.034) Our package of the week this week is the Maui Community Toolkit because those guys work hard on that thing. They ported it. I think it was ready day one and they're still working on stuff. Jon (59:29.71) Oh yes, I forgot almost! Oh, package. Yeah. Jon (59:40.106) Yeah, and it's got a ton of stuff in there that's useful. I, you know what, every once in a while, I go back and look at like what's been added. And I realized, oh, I could get rid of a bunch of my own things because they've got different like converters and behaviors and all these different things that are just super helpful. Allan Ritchie (59:56.53) And I don't want to make a call. I'll just make a call out to the team. Cause I know there's a bunch of you that have been there for a while. So it's no disrespect. You guys are awesome. It's just, there's your change in size all the time, but like there's some big contributors that have been there for a while and you know, you guys are doing awesome stuff for the community. Jon (01:00:01.997) Mm-hmm. Jon (01:00:09.707) Yeah. Jon (01:00:13.598) Yeah, those extras and everybody that works on them are definitely super helpful. All right, I think that'll do it. Thanks, Alan. Thanks everyone for listening. We'll see you next time on another Gone on Mobile. Allan Ritchie (01:00:27.31) Thanks, John.