AppForce1: news and info for iOS app developers

Azam Sharp on his Aggregate Model Architecture

December 26, 2022 Jeroen Leenarts
Azam Sharp on his Aggregate Model Architecture
AppForce1: news and info for iOS app developers
AppForce1: news and info for iOS app developers +
Help us continue making great content for listeners everywhere.
Starting at $3/month
Support
Show Notes Transcript Chapter Markers

Send us a Text Message.

Azam and I discus some architectural ideas Azam has developed over the course of over a hundred sample codebases.

Runway
Put your mobile releases on autopilot and keep the whole team in sync throughout. More info on runway.team

Lead Software Developer 
Learn best practices for being a great lead software developer.

Support the Show.

Rate me on Apple Podcasts.

Send feedback on SpeakPipe
Or contact me on Mastodon: https://hachyderm.io/@appforce1

Support my podcast with a monthly subscription, it really helps.

My book: Being a Lead Software Developer

Jeroen Leenarts:

Hi, and welcome to another special edition of on podcast. I'm sitting here with Sam sharp. And he's been on the podcast before, close to one and a half year ago. And recently I increased online if there were some people interested to be on the podcast. And as I'm actually raised his hand and indicated a very good reason why he wants to do that. And the reason he wants to be on the podcast, again, is to discuss some of his learnings about Swift and swift UI development, because he claims that he has created over 100 prototypes in the last three years, I think he said, and that's quite an interesting journey. So first of all, welcome back, Sam, how you doing today?

Mohammad Azam:

Yeah, I'm doing great. Thanks for having me.

Jeroen Leenarts:

So you specifically mentioned that you wanted to talk about your learning path into Swift and swift UI over the past three years? Because people who do not know you, they should look you up online, because you have some wonderful material available for people who are interested in learning more about Swift iOS and Swift UI development. What am I missing here? What else should I share? Before we dive

Mohammad Azam:

in? Yeah, sure. So I have a popular YouTube channel close to like maybe 18,000 subscribers. I also have 72,000 students on Udemy. And I think it's like around 1012 courses just on Swift UI. But I believe the total courses are over 30, I believe, which are covering swift UI, Firebase vapor, you know, a lot of different stuff. So definitely check out the courses on the on Udemy. Part. And definitely check out the latest courses publishing out. But yeah, mainly a publish on Udemy and YouTube.

Jeroen Leenarts:

Yeah. And as always, I will make sure to link everything in the show notes. So by the end of the show, we'll probably mention few of these links again, and but look at my show notes. And I will make sure to list them there. Just to dive in. You mentioned three years to me and over 100 prototypes. So what's the what's the idea there? Because you must have had a reason to like really experiment this much with code, right?

Mohammad Azam:

Yeah, so most of the prototypes were actually small projects that I was doing for my Udemy courses. And I recorded, I think, like 10, or 15, or 10, or 12, at least, courses just on Swift UI and presentations. So most of them were related to that. But one thing that I started learning is, and this is where it becomes a little bit more controversial, which is good for I think my podcast is, for last three years since 2019 2021, whatever I was using, which everyone was using MVVM design pattern. And I was one of the biggest proponent of MVVM. I wrote books on it spoke at different conferences, articles, even courses on MVVM. But after I do these apps, when I started doing these apps, and more and more apps, and the way the app complexity was going, the pattern was kind of like coming in the way. So once I was I think doing the MacOS applications, I was like, Okay, this doesn't seem right, there is something wrong with what I'm doing, or there's something wrong with serve UI, or how I'm applying these patterns. So for three years, I start doing or start creating apps using MVVM. And then after three years, I'm like, this is not working out, there's something wrong, like I cannot access the environment object, I cannot access the focus state, I cannot access the, you know, gesture state inside the view model. And it's just a pain to pass those dependency all the way down to the child elements to the child views. It's just a very much a pain. And even if you pass the dependencies down to the child, or children, then you're lost, like okay with who's maintaining the dependency, because now it's like all over the place. So I went back to the drawing board, I started reading a little bit more on how react works. And I found it interesting post online, actually couple of interesting posts, that were talking about the same thing that I was experiencing. And they were talking about how you should not be using MVVM to create some view application, because it's not a wrong pattern, per se. But so if UI is already a pattern, you should not wrap it around with another pattern. And that's I found it very interesting. And instead of like telling that person whoever posted like you're wrong, and you don't even know what you're talking about, instead of that I tried to communicate with and I tried to contact that person. And we started talking on Twitter and he was sharing some ideas. I shared my ideas and we came to the conclusion along with some other people is that it's just not, at least for our apps clients or web application, at least, it was not making sense to use MVVM to wrap our whole, you know, Swift UI with MVVM framework or MVVM design pattern. And we in the end, we found out that serve UI is already a pattern. Instead of wrapping it with other stuff, we should just use how Apple is trying to tell us how to use it, which is in their code examples. Now, this is not to say that, okay, you should go back and take out all the MVVM stuff and replace it with a different pattern. Now, if your app is working out, you should just keep it because there is always a learning curve on new patterns or new techniques. So I would just keep it that way. Just look at different experiment that other people are doing, maybe you will like those things. So at that point, yeah, they will only like few peoples in the community, maybe a handful of half a dozen that were talking that were saying that there is something that we are missing. And I will also eventually become part of that one, and kind of admit that I was doing it wrong, for close to three years, especially for client server based applications. And what we learn from watching the videos watching how React is doing stuff, is what I learned is the view itself has the capability of binding. So it doesn't really need any help from a separate view model file. So we went back, I mean, I went back to WPF, Windows Presentation Foundation, which was in Microsoft, and I looked at how Microsoft was doing things because this is where the MVVM pattern, you know, evolved. And in WPF application, we had zamel file and the C sharp file and they were like gonna like link together, whatever you type in the zamel file, it will be binded to the C sharp file, which contains the view model. But in our Swift UI, the view consists of all those property wrappers like state and all that stuff. So it doesn't really need any help from a separate view model. So we start looking into this pattern and more, I experimented with it and started converting my apps, the more it become very clear that this is the way that Apple wants you to do this stuff, you don't really need a view model for every single screen that you're going to be building. The view has the capability of binding, so why not just use the view itself. So a very quick example can be if you're building something like a login view, which contains a user name, textbox and a password textbox. If I'm using the MVVM pattern, I will start with login view model. Well, I don't really need a login view model. I mean, the login view can contain two state property records, one for the username, one for the password. And that's it done. And you can validate inside the view, the validation is just checking that you put the username, and you put some sort of a password. But that's pretty much it. That's not business logic. That's just basic UI validation. And I wrote an article on it, it was a very initial article where I guess I didn't do a good job of explaining this kind of not a new pattern, but what Apple is recommending or what Apple is doing. And people were like, Oh, you mean, like put everything inside the view? I'm like, no, no, no, that doesn't make any sense. No, you should not put everything inside of view, you just don't create a view model, what you do is you create what I like to call an aggregate model, meaning just one model for the app for a small app, you just need one model. And your view will communicate to that model. And that model will communicate to the web service, the web service will communicate to the server, get back the data, and it will pass through the failures backwards. So that is the architecture that I'm using, at least for my applications. And it's actually turning out to be really good, I can take advantages of the environment object, I don't have to pass any dependencies. I can use focus, there's just a state environment values, whatever I need, I can just do it inside the view. So that was definitely a turning point for me to to create myself UI abs in a very different way.

Jeroen Leenarts:

But but it isn't in a way making sure that the data that is being handled in your app, really at the center of everything that you're doing right because the view hierarchy manipulates this this model of data that you have that is at the core of your application, but then at some point this this data needs to be transacted upon. So either it needs to be transformed into something else or it has to be sent off to a network location to be handled there. So is it like a Also that not only from the few hierarchy side, but also from the networking sites and other areas within the logic of your app that you try to work with this data in a more reactive way, or how are you looking at this.

Mohammad Azam:

So I'm just looking at it in in mostly in your simple applications, your design will be or your architecture will be in basic, like simple applications, your view, will communicate with something called an aggregate model, you can call it facade if you want, if that helps. And that aggregate model will be responsible for providing the viewer with all the data it needs. So let's say that view needs the list of products. So that particular aggregate model is going to use a web service layer to get all the data and then just hand it over to the view using published properties. Now, if you have a much complicated application, much bigger application than one model, one aggregate model is not going to do the trick. Because you might be dealing with a catalog for E commerce, you might be dealing with, you know, inventory fulfillment. So you can create multiple of these facade or aggregate models. And those will be responsible for whatever they want to do in that particular domain, in that bounded context. So a catalog, aggregate model can return you a list of product, product items, categories, but the fulfillment will be related to dealing all the operation related to fulfillment, whatever that domain does. So in the end, it's similar to the MVVM. But we removed the requirement to create a view model per every view, that makes it simpler.

Jeroen Leenarts:

Yeah, because you're basically relying on the binding behavior from straightaway into your model to make sure that all the data gets well taken out of the model and pushed back into the model. And you and is there like, is it more like a technical reason that you choose, at some point to split the models into separate aggregate models? Or is that something that is more related to how you, as a software developer, then can deal with a lower cognitive load when working with this data?

Mohammad Azam:

Yeah, I think my theory is that, for simple applications, you will only need one aggregate model, you can even call it model, that's fine with a capital M. Yeah. And that will provide you all the data you need with like different, different structs. So there'll be one struct for product and category and category items, and sorting behaviors, and filtering behavior, all of that stuff, all of that implementation can go inside that particular model. But as your business needs evolve, and now you need to keep track of, well, I need to do catalog, I need to do inventory, I need to do fulfillment, then you start adding different aggregate model or facades, whichever one you want. And those will be responsible for giving you different kinds of model data that will be displayed and manipulated on the screen. Now, from the view perspective, for simple screens, which only have few text boxes, three, four, even five, the view itself can populate those text boxes in just a state variable, and then pass it down to the model. That's perfectly fine. Now, if you have 10, or 20 different fields, maybe you're creating a page or a view, which is responsible for driver license registration, which is a long page or long view, with a lot of fields, maybe at that point, it's a good idea to create a separate struct, which is responsible for holding that data. So you don't have like 30 fields 30 state variables, in a one view, you have that separated out into one or multiple, different structs, which you can say it's a view model, that's fine.

Jeroen Leenarts:

But in your way of working these aggregate models, they're not just data, right? They they also do other things with the day to day massage the data in a way that it's like sorted or the or worked upon, so are filtered for example, yes. Would you then on this aggregate model also have logic that actually initiates a thing like a network call to a web service or an end to web service handling and error handling and all the details and minutiae of that is basically handled in probably some service object?

Mohammad Azam:

Yes, yeah. So the aggregate model is responsible for providing you the data in terms of those struck models like product category, user customer, whatever accounts to those small models, by an aggregate model is also response. trouble for initiating the call to the web service or call to the network by using the network service layer. So it's not going to do it on its own. It's going to ask the network service layer or the HTTP client layer, that hey, can you give me all the products and then the service layer, the network service later is going to fetch all the products and assign it to a, basically a products, property or public property on that particular aggregate model. And then it will be obviously automatically refreshed, the view will display it.

Jeroen Leenarts:

Yeah. Yeah. And then I can imagine that if you, for instance, try and get a list of orders from your back end, that you then on your aggregate model, have a function called fall, let's just call it get orders, right? Yes, you just want to fetch those, or maybe fetch orders, whatever works for you. But it sounds to me like then the the aggregate model is a really nice place to branch off work on a separate track, right. So that you have I think you can really use async await at that level there to make sure that you do something in the user interface, the user interface does not get blocked. But once the data callbacks, it's it's populated in your model. And because you're binding to the list of orders, in your model, the view updates.

Mohammad Azam:

Oh, absolutely, yeah, so most of the functions in my aggregate model, like fetch products, get products, or whatever, they are async functions. And obviously, the function in the web service itself, they are also async, because that's where I will use the URL session, dot shared or whatever, to make the call. So that kind of helps to put all the data in one central place for small apps, at least. So that you know, exactly, you know, where the data is, what is the state of the data. And it's sometimes that in most of the time, at least, for me, it's I can just inject the aggregate model object in the environment variable environment object, so that it is available in the view that I injected plus all the children. So then I can simply use the environment object to get the actual data out and displayed on the screen. So it's much easier for me.

Jeroen Leenarts:

Yeah, but but you will have the situation that the aggregate model is sort of like a pass through thing for operations that reach out into the network, right. But what if you have some form of caching going on. And it's not a typical low level URL caching, but it's a higher level caching? Is that something that you would implement in the in the surface layer or in the aggregate model layer, then

Mohammad Azam:

you have a choice, I think, in those cases, I would just create a different layer for caching, and then use that layer inside the aggregate model. So that if it's available in the cache is returned from the cache don't even bother the web service layer. And if it's not available in the cache, or maybe the time has expired, then yeah, go ahead and get this latest stuff from the cache.

Jeroen Leenarts:

Yeah. And it sounds to me that this very straightforward layering that you put in your application, because basically, you have a surface layer that does like networking, asynchronous file, io, whatever. Then there's like a model layer. And then there's a few layers. So it's basically a three layer system. And what's the furthest in complexity and size that you have taken this idea?

Mohammad Azam:

I've created some apps that had multiple aggregate models. One is like an E commerce application kind of scenario. But one of the people that I was talking to the while they're using a very similar model is called Well, little bit simpler than using like an active record pattern for their approach. And they're creating a full fledge application with like six to eight people working on it. But for my case I work with are converted basically all the application that I was doing before, and it was much easier to use, because I was not dealing with like 30 different view models. I just have where, like, one or two view models if I need to. But for me, I think it was like two or three aggregate models. I think that was where I was working with.

Jeroen Leenarts:

Yeah. And but how does this work? When you want to do some testing on your on your code? Because it seems to me that the three layers are well, quite tightly bound together? Well, not not from not bottom up, but from top down. There's a large dependency, of course, between the deeper layers within your app, right?

Mohammad Azam:

Yep. Yeah. So I wouldn't say I mean, tightly bound or anything, but I think most of the people who did testing or one of the question they always ask me that, well, how do I test it? Yeah, cause wait The MVVM approach, I can just go ahead and test it using my view model, I can just create a instead of a view model, I can say on whatever, like, increment or whatever function I fire, and then I can see that the view model is getting populated or not. Yeah, I don't believe that Dota those tests are any useful. I think. I mean, I've seen those hundreds and 1000s of these kinds of tests for view models and view controllers. But I don't think they're testing anything. They're just testing the implementation details without testing the behavior itself.

Jeroen Leenarts:

Yeah, I've seen tests that pretty much like okay, I populate property and I read property, yes, the same value comes out. Wow, amazing.

Mohammad Azam:

And what these tests can actually doing is if you're using the MVVM approach, or any approach, I mean, I don't want to say MVVM is bad or anything. But if you're using MVVM, model, or even the view controller in UI kit, usually, for these tests testing, what you do is you mock out the web service layer, you mock it out, you say okay, I'm going to mock it out, I own the web service layer, but I'm just going to mock it out, I'm going to pass it as a dependency, when the, when this is called, then make sure that my view model property gets changed. Well, if you're writing a test that is checking for an expectation, on your view model that a property of a view model will get changed. That's the wrong test. Because that is testing the implementation detail, and not the behavior, if you refactor your code and simply change the name of the property, and but the behavior remains the same, your tested start going to fail, which is incorrect, which shouldn't happen. And these that's why these kinds of tests are very, very brittle test. Even if you refactor your code, and the behavior remains the same, the test will start failing, which is not a good idea. So now we go back to the customer, how do we test them? Well, we test writing a real integration of end to end test, like end to end test means your simulator is going to launch you, the simulator or the test, if you want to write something in a text box, press the button, and then you're going to check for the behavior against the real test server, but not something that is mocked out. That is not saying that mocking is bad in all the scenarios, but you shouldn't be mocking heavily for things that you have access to, yes, if there is a payment gateway, and every time you access the payment gateway, they charge, you should probably mark that out or at Twitter framework, whatever, you don't have access to that, you should do that. But heavy mocking, which is being advocated when you're testing your view controllers and view models that those tests are not a good return on your investment.

Jeroen Leenarts:

But it does require a lot of control on the deeper layers of your architecture, right. And then I'm talking about architecture of the entire stack, not just the app, but also stuff that is behind that, right. So you have to have like a test environment that is somewhat stable, so that if you run if two people run the same test suite, at the same time that they don't interfere with each other is that complicated to achieve or that that

Mohammad Azam:

yeah, that's definitely one of the bad sides, I guess of end to end testing that there is the initial setup that is required. If your server if you're doing end to end testing, then you will have to make sure that your server is performing all the migrations to create the database to create the table, maybe add some seed data, insert the data into the tables that you are inserting, maybe you're adding a new customer, verify it, and then delete the data, because you can't really read a live data in the database, because it will fail the next or the future test. So that will require a little bit of quite a bit of a setup one time hopefully one time setup. And, and then again, they are slow also, so end to end test is not answer to everything, because they are also slow. But they are slow, because they are end to end. You know, I mean, they check all the layers. So you may not run them every single time you check in the code. But then you will have to decide when to run them frequently, but not as frequently. So to slow you down.

Jeroen Leenarts:

Yeah. Yeah. So So probably you need some sort of smaller units testing still to test certain aspects of your tech stack. Because because you don't want to run the integration tests like every minute. Because yeah, probably the integration test takes a little bit longer than a single minute. But is this integration testing? Is this something that is typically done on the developers machine? Or is it more done on CI? And that is automatically done when you push your code to a central git repository or what's the what's your thought process there? Because I can just imagine that if you have like a good group people developing your backends, there's a good chance that they actually are doing that in some sort of containerized way, and that you can most likely run the entire tech stack, or at least the critical parts of the tech stack that you need in in the local Docker environment. For example,

Mohammad Azam:

yes, yes, for end to end testing, which covers like the whole layer of everything that should be learned run under very fast CI server, continuous integration server, because the it will take a lot of time, depending on how many tests you have. Now, if you're building a client server application, where Sophie Why is obviously the client, and server can be in whatever doesn't matter node or Express js, then 100 to a 99.9% of the time, your actual logic of the application, the domain will be living on the server, meaning on the JavaScript side on the node side, or SP dotnet, Ruby on Rails, whatever. So that has to be tested thoroughly like like really, really well. Kind of like if you're building a bank, system finance system, you must test out your server can deposit the money into the bank, withdraw the money, transfer the money, and if there is a insufficient funds, then make sure that you charge overdraft fee because that's like, that's that's the money in the bank. Basically, there's like a $2 billion difference for these banks sometime $5 billion business. So those are the moneymakers. So that core, or the domain has to be tested thoroughly with unit tests like plain ol unit test on the server. And then we will obviously if you're exposing your API to someone else, then the public API needs to be tested thoroughly using integration tests or unit tests, whatever. And then the whole system, all the layers have to be tested. And usually end to end test tests are usually run on CI server because they are slow in the end.

Jeroen Leenarts:

Yeah. And but I can imagine that if you really step back and accept that certain aspects of an app that you're building is pretty much a JSON based rest surface browser, because that's what many apps actually in fact are. You can make a distinction in your code base that if it's really like, okay, calling web services and dealing with the results of that, that you then accept that the testing that you do as an app developer, it is more on the integration level. And if there's other logic within your app that is, well, less bounce to the web serves as more logic and self standing on its own, that you then in fact, do our work more on the end to end testing of that logic. But of course, if you look at an integration test that you would need to do on such a piece of code, for instance, you need to do some processing on an image or whatever. That is something that you can test end to end as well. But that's just because of the fact that the end results of your test. They don't leave the system, or at least they you can test in a state that you don't have to have network interaction at that point. But you still have a meaningful test going on? Because yes, there's actual logic, actual complexity being processed on some inputs, that should present a certain output, right?

Mohammad Azam:

Yeah, yeah, I think if, if our app is simply which most of the soap UI apps are simply consuming the actual data from JSON service, and then obviously, the server people or whatever, they're gonna test the server side and the public API's. But as a soap UI developer, I will be definitely be more focused on end to end tests writing and consuming or integration tests. In this case, I guess, yeah, integration tests, checking that my client, the behavior that I'm trying to achieve is tested through my swift UI app launching, simulating those events, filtering the options, and although thing against the real life test server, definitely that will be much helpful.

Jeroen Leenarts:

And what kinds of techniques or frameworks or things would you suggest? Or are you actually using yourself in these integration tests, I can imagine some UI automation. I can imagine some scripting to influence the back end, or maybe even have a dedicated command line client for the back end that you can call from your tests, right?

Mohammad Azam:

Yeah, for my integration tests, and since most of my end to end tests, they're most of them are related to node and express because my server on the safe side, I'm using just a basic x unit, or XC, like a UI test framework that they have the building. And you can change the configuration. I mean, you can write some code to check if it's running on UI tests and you the test server routes or URL, but you can also make those build configurations and simply the whole configuration will be depending on whatever the build target that you select, so you can have like a lot of variables in there in the built in the build file. From the server, yes, server becomes a little bit more complicated when you do end to end because now you have to create the database, you have to do the migrations you things, if you're using SQLite, or which whichever database or technique that you're using, and that will reside on kind of like on the server side to do all of those things. So that is where the complexity comes into play. And that is where it takes a lot of time to drop those database, build it up, again, for every single test. And I think that's where the slowness comes into play. Also, I think, in the end, for me, it's most more about since all the tests are not equal, like one test, they depending on what kind of apps that we're building the test for depositing money and withdrawing money and charging the user withdraw, I mean, the penalty or whatever, for insufficient funds, those kinds of things will be more important to me, or more must be because they actually create revenue for the company. But we find creating a find have created a logging engine, which are logging framework that will log when you log in and log out, it will be kind of like at the bottom of my list because okay, it didn't log whatever. I'll get to that when I will get to it. Because, you know, I mean, that can be tested, but it's not as a high priority.

Jeroen Leenarts:

Yeah. So yeah, because I'm thinking about if people want to learn more about this approach, I know you wrote an article on this. And it's, I think you wrote that in October, if I'm correct, a few months ago. But have you already been able to create some, some some more information about that, because the initial article that you wrote about it is, is really like just dropping down the idea? And probably getting some responses and communication and some discussions going on that. So but that's the initiation of the concept and the idea, but where are you at now with exploring this idea in this concept? And is it already something that you feel that has enough proof in your mind that it is it is usable? An actual sound way to go about setting up an app?

Mohammad Azam:

For me, it works. I mean, that's all I can say. And I think initially when I posted the idea, and I'm just checking, it was a few third couple of months ago. The latest article on that is, I'm not sure the date I think it was in October 6 2022 is the latest one, which was about which is called swift UI architecture, a complete guide to MVC pattern approach. And then I did also a little bit more article on core data, how you can embrace core data with Swift UI, and how you can evolve with Swift UI architecture for client server apps. So I have been evolving it in terms of core data and client server apps. But I think if somebody has to read this article, I would definitely check out the Swift UI architecture, complete guide to MVC pattern that's most updated, I think, our article.

Jeroen Leenarts:

Yeah. And, of course, view being you. There's probably also a Udemy course about that, where you explore this concepts a lot more, right?

Mohammad Azam:

Yes, there is a Udemy course that I published, I think, this year, and it's called MVC design pattern. And iOS builds a few apps apples way. So after talking to a lot of people and getting into issues with MVVM, I went back and watch all the videos of surf UI, and try to bother like, very, very slowly try to see all the code that they're writing, definitely check out their code for the food truck application. That is, I mean, that's a decent size app. I mean, somebody can say, well, it's gonna work on a small app, but it's not going to work on larger well defined large. So that argument, that argument in itself is self defeating, because they cannot define large what's the Lord's app 2 million? Well, how about if I work with 10 million lines of code for me 2 million small, there we go. With the largest relative not absolute. So that's another problem. So but yeah,

Jeroen Leenarts:

but you at the start of this conversation, you we mentioned that? You did like 100 prototypes. So these 100 prototypes. Can you again, tell me why. In your sound mind, did you come up with the concept of hey, let's create like a gazillion prototypes and just see where I end up? Because there must have been some process to the madness, right?

Mohammad Azam:

Oh, yeah. So prototypes. I started creating for my courses for sale. UI. So when soap UI came out 2019, I started working on my first scores, which contains like, a lot of different apps. And somewhat simple, somebody a bit more complicated. So during those three years, I created like hundreds and hundreds of prototypes using Firebase using core data using just a few I, using realm, I mean, so many different frameworks I had to use. And initially, I was using MVVM pattern. And it was working out but it was like, I had to always have to like, Okay, I need to pass a dependency into a dependency into a dependency, that I don't want to do that anymore. So that is where I was like, Okay, maybe I'm doing something wrong over here. Because then I started looking at React also, because react and so few, I pretty much the same thing. React people are a little bit more crazy than so few people because we in React, they have components and right inside the component, they will make the network request, just fine. I mean, yeah, sure, if you think your component is only going to be displaying and not being used somewhere else, you can perform the fetch request, which will basically a network request, get the data and display it on the screen. I mean, that's fine. And since you I also, I don't have problem with that, it's a little bit too liberal for my tastes, at least, I mean, I would like to have a little bit more separation. So that's why I have that responsibility to the aggregate model or facade, which calls the web service layer. So I'm a little bit more future proof if the app goes into much bigger. So that is my view of that.

Jeroen Leenarts:

Okay. So just to recap, you did like a lot of experimentation. And then you came to the conclusion that you think, on a general level, when developing swift UI code, we're doing it wrong. And the doing it wrong, is that we just add a lot of architectural complexity layering, because most likely, that's what we are used to coming in from UI kits. And that's also what we need it when dealing with UI kit to keep the complexity in check. How do you feel about having these aggregate models and just making them available in the in the environment of Swift UI? Because some people will immediately say, Yeah, but that's like you're creating a global and in some languages, some frameworks that's, that's a bit of a no, no. But what's what's your stance about that in Swift UI,

Mohammad Azam:

so not every time I put it in that environment, but most of the app I'm making is, they have the capability to edit or update and delete in different views. And it's easier for me to have that available in the environment, instead of passing down as a binding property. So sometimes I can use state objects, sometimes I can use observer object, but it sometimes I mean, most of the time, it makes sense for my apps to because I'm creating, create, read, update, delete all the operation, to put it in environment. Now environment is not technically a global object, because it depends on where you're injecting it. So you can inject it on the root. And it will be available to the root and all the child of the root. And I think there's one very big misconception, which I also had was about when that sort of UI recreates your view re renders your view, because I was under the impression for a long time that, Oh, you just put a self dot print changes inside the body property. And whenever that fires, okay, all the view is gone and recreated from scratch. But that is actually not true at all. The body property, if you put a self dot print changes, or hello world, something inside there, the body property, when it fires is only telling you that the body is being evaluated right now. It's not being recreated. So Sofia is quite smart. Because if something change in your view, if you're incrementing a counter, and you're displaying a counted in a text field, but you also have a text, sorry, a text view, and you have a list and you have a button and you have a picker view and a segmented control, blah, blah, blah. So if you're not going to recreate all of that stuff, because all of none of that stuff is using the counter value that just got incremented it's only going to update the text view because that's the only one chord change. So during the evaluation process is going to make a diff meaning differentiation between the new tree and the old tree. And it's going to find out that oh, well, there's only one control the TextView that actually use the counter. So all of these other five controls, I don't have to recreate them. So I think that's the good thing. And that is what also happened with the environment. Just because you put something in the environment does not mean here the whole app is going to refresh and rebrand. Under, it's only going to read under if that particular view is using the property of or from the environment.

Jeroen Leenarts:

Yeah, yeah. And that's, that's there's a lot of smart diffing going on in the background, to actually see what has changed between the view hierarchy as it is encode and what is actually on screen. And you can trip it up. Sometimes it does more than you would like, but then there are ways to get around that. So but just to, to well to to start closing things off a little bit. We already mentioned some of the articles and some of the coursework that you did on the MVC design pattern. And but what I'm also curious about is last time we spoke on the podcast was sometime in the summer of 2021. What has happened since then, what have you been doing? And what are some of the successes that you do you have in the well, I think close to one and a half year already?

Mohammad Azam:

Yeah, I've been busy obviously teaching, that's my full time job. I think I was teaching my 13 or 1414 cohort for for the company that I work for digital crafts. And then very busy in I think I published I published two small books, one of the navigation API, and one on UI kit with a few recipes. Both are available for free. During the holidays, you can get it for free completely. And I also published an actual hardcopy book, which is about the boot camp, which is surviving the coding boot camp. It's a small book hardcopy plus ebook also. So that contains a lot of advice related to which boot camp to attempt to enter and what goes into boot camp, how to be a successful student, because I've been teaching for six years now. And doing like some independent work on the side sometimes. But and yeah, of course, a lot of courses I developed like MVC design pattern. The new course I just published, like maybe couple of weeks ago was about UI kit, because they were people were like, Hey, you forgot about you. And Katie, you haven't talked about it for a long time. Um, okay, here's the code for you UI kit with completely programmatic approach. No storyboards, no, nothing. So, so yeah, definitely fun.

Jeroen Leenarts:

Suggest just dabbling server, some old school iOS development, just for just for the heck of it,

Mohammad Azam:

just for the heck of it.

Jeroen Leenarts:

And as the iOS related teaching that you do on the side, because your main job is, is doing coursework for a company, but you do the iOS stuff on the site is still doing for you what you intend it to be doing for you just create a little bit of extra income for you and your family to, you know, just do the occasional fun trip every now and then. And are some other extra expenses that that just make living. That little bit more enjoyable for you and your family.

Mohammad Azam:

Yeah, definitely. I think it's just extra income that, you know, I like to travel. So I usually do sometimes those trips for hiking to Colorado or wherever. And some time I we just came back from beautiful Mexico City, the whole family vacation, or nice couple of weeks, I think three weeks ago or something. Yeah, that was fun. And yeah, I'm, I consider myself a little bit of a finance guy. So I do invest a little bit of money on from that into mutual funds. Very simple stuff. But yeah, it's been it's been fun. And I think what these courts have allowed me to do is to kind of like, take a step back and think about those things. Because I know that when we are on the clock, we have to type some time, we're not really thinking that much. But now, it has allowed me to kind of like slow down, think about things and then write about it much more better than just completing these tasks and all that stuff.

Jeroen Leenarts:

Okay, cool. Sounds good. Seems you're still in a in a very good place with your work and how are you enjoying it and how you spending your time? Where should people go look to find everything that you do online?

Mohammad Azam:

The best way would be Twitter. You can follow me at awesome sharp AZ am sh ERP. And yeah, if you follow me on Twitter, you'll get to know about everything that I'm doing because I am quite active. Yeah, that's the best way.

Jeroen Leenarts:

Okay. I will make sure to link that in the show notes. And yeah, I think I think we covered what we wants to cover in this conversation, I think.

Mohammad Azam:

Sure. Yeah. Absolutely.

Jeroen Leenarts:

Okay. Thanks for your time and talk to you next time.

Mohammad Azam:

Sounds good. Thank you for having me.

Introduction
Is MVVM a wrong pattern for SwiftUI?
How do you test your view models?
What is your stance on having aggregate models available in the environment of swift UI?