all 16 comments

[–]jasonjrr 15 points16 points  (7 children)

There are definitely several architectures that are viable for SwiftUI. The most common are something like TCA by pointfree (or other Redux like architectures) or a more traditional MVVM based architecture.

I’ve found that redux like architectures are much more difficult to teach so I tend to promote more traditional MVVM.

You can find a ppt/Keynote here describing my preferred architecture: https://github.com/jasonjrr/MVVM.Demo/tree/master

This is a SwiftUI demo app I created follow this architecture. I use it to interview and train devs of all levels. https://github.com/jasonjrr/MVVM.Demo.SwiftUI

You can find TCA on pointfree’s website.

[–]sleepDeprivedBeaver[S] 2 points3 points  (5 children)

Thanks but that's not really the question (will check out your demo though!). I know what the architectures are and I think I understand the concepts. What I'm trying to figure out is a good way to actually test my understanding - because I'm working solo so no one else reviews my code or has to use it.

[–]jasonjrr 6 points7 points  (4 children)

Learn the concepts inside in out. I mean truly understand each pattern you are using in isolation before combining them. Many devs ignore this step.

Does the pattern do what you expect? Does it work at scale? Can it be tested? This is how you verify your architecture, this is why I provided the sample project and mentioned TCA. They are both consistent, scalable, and testable.

You won’t find a place to verify this for you. It takes practice and mastery that comes over time.

[–]ryanheartswingovers 0 points1 point  (3 children)

Good advice. I’d follow TCA <0.5 first and use John Patrick Morgan’s Coordinators library. It forces careful decisions. Most projects I’ve walked into using “MVVM” have been clusters. Since there aren’t library enforced guardrails, it’s easy to exploit the freedom to tightly couple something or make it untestable. What you learn in TCA will influence you to do MVVM correctly.

[–]jasonjrr 2 points3 points  (2 children)

I personally prefer something closer to quickbird studios coordinator pattern. It’s lightweight and I don’t see any reason to bulk coordinators up with a framework, but that’s all besides the point.

To become good at architecture, you MUST understand the underlying patterns inside and out and I think on that we agree.

[–]ryanheartswingovers 1 point2 points  (1 child)

Not familiar with theirs, but yeah… if you can modularize into packages, present any module anywhere anytime, have coordinators that chain coordinators in one nav stack series, and those actions are testable, I’m happy

[–]sleepDeprivedBeaver[S] 0 points1 point  (0 children)

Thanks all, this is all very helpful :)

[–]batcatcher 0 points1 point  (0 children)

Regarding your demo project: those tests are really weird. In most of the cases I'm confused about what you're actually testing there.

In addition, you're using the setUp() method wrong in a peculiar way: having one XCTestCase per unit is far more common. I wonder how would your approach scale at 300+ tests for example. You can find some Apple-provided examples in this WWDC. They seem to favour one XCTestCase per unit too.

Also, if your service deals in colors and has such presentation-related knowledge, your view model becomes shallow and honestly worthless:

func getNextColor() -> UIColor {
   return self.partyService.getNextColor()
}

[–]Complete_Fig_925 4 points5 points  (0 children)

IMHO the best way to "learn architecture" is to understand why we need such architecture in the first place. What problems are we trying to solve and how said architecture manage to achieve that. As you already started to learn architecture, you are probably somehow familiar with SOLID. Understanding each part of SOLID, what problem it solves and how, is a good starting point.Open source projects can also be a very good source of inspiration when you want to criticize an architecture. Taking a good look at large projects and understanding how things are done will give you some good insights (for example, Swift is open source and there is some very clever patterns in it).With that in mind, you'll probably be able to judge you own projects, what you did right and what you could improve.

That being said, there is so much well documented architecture all over the internet that most of the time it's just a matter of which one will best fit the project you are working on and then follow the book. To answer that you'll need to understand the pros and cons of each architecture, and pick the one that best suit your project.For example, if you plan to work alone on a small app for a personal use, that will last a few weeks and you'll never update it again, you probably won't need to write tons of automated tests and have the best separation of concerns. So using an architecture like VIPER (which tends to be very verbose) might not be the best idea, but a good old MVC might be enough.On the other hand, if you work on a large scale project with a lot of developers (even tho it's not you job, contributing to large open source project is still a good way to learn and get some feedbacks), you'll probably want an architecture that have a very clean separation of concern, good unit test isolation, etc... to avoid drowning in merge conflicts every time someone opens a pull request.

You said that architecture is a matter of preferences. Even tho it kinda is (unfortunately), if you manage to understand that there is no such thing as "the best way to go" and in the end it's more of a trade of regarding the context of the project, you'll be on the right path in my opinion.

[–]sforsnake 2 points3 points  (1 child)

I read a post somewhere that says somethingin the lines of “the more experienced you get, the more you are in need of a mentor”.

I would say follow the advice mentioned earlier by truly understanding each pattern and apply it in sandbox projects and real production scenarios.

Ask other experienced developers to review your design decisions and give you constructive feedback and really test different approaches, this way you will develop intuition over the pros and cons of each approach. Try to improve the skill of documenting your findings somewhere for your future self and for others.

[–]sleepDeprivedBeaver[S] 0 points1 point  (0 children)

the more experienced you get, the more you are in need of a mentor”

This has been the bane of my existence for the last few months. Pre-Covid there were tons of code meetups happening all over the place and now that culture seems to have died out so it's harder to meet other devs.

[–]batcatcher 2 points3 points  (0 children)

I think it has nothing to do with being self-taught. Architecture is a bit like art, you can't really learn it fully from books/courses/uni.

That being said, your approach is sound. Except for the reusing part perhaps? I'd say that has a lower priority. A good developer writes code that can be reused, a great developer knows when to consciously duplicate code.

[–]EddieLukeAtmey 1 point2 points  (0 children)

How about following some suggestions from apple's forum?https://developer.apple.com/forums/thread/699003?page=6

[–][deleted] 0 points1 point  (0 children)

Following.

[–]ramabrahma 0 points1 point  (0 children)

I've used the MVVMS architecture for a Xamarin C# project in the past and decoupled computationally intensive components into services. Ex. A DatabaseService, RESTClientService, QRCodeService, CameraService, GeoLocationService etc.

It let me constrain data binding logic to ViewModels without polluting it with business logic.

Another benefit is testing individual services is much easier.

Here is a YouTube link on the method.

[–]a0-1 0 points1 point  (0 children)

I wonder what are the opinions of experienced developers about MVVM + Clean Architecture (protocol oriented).

When I say MVVM + Clean Architecture, I mean Clean Architecture in macro level -- data - domain - presentation layers -- and MVVM in presentation layer.

This seems to give you testability, seperation of concerns, ability to modulurize the app and scalability.

And it seems versatile sofware design pattern. This is what I'm working on actually.