SwiftUI MVVM

Search for a command to run...

No comments yet. Be the first to comment.
Navigation in your app has to be appropriate: Don’t use non-logical navigation. Navigation must always be intuitive: Users don’t have time to look for the right section in your app Don’t steal time from your users: They will delete the app Navigat...
EnvironmentObject is useful when you want to create a dependency in a higher component of the layout tree and use it on a lower component without having to pass it down the tree through every child component. We will now use EnvironmentObject to moni...

CompositionLocal is useful when you want to create a dependency in a higher node of the layout tree and use it on a lower node without having to pass it down the tree through every child Composable. Here we will use it to direct our application when ...

The TDD (Test Driven Development) approach is important when it comes to testing small portions of business logic code in isolation. In this blog, I'll cover how I would use TDD to build a clean architecture To-do SwiftUI application I'll cover imp...

The TDD (Test Driven Development) approach is important when it comes to testing small portions of business logic code in isolation. In this blog, I'll cover how I would use TDD to build a clean architecture To-do Jetpack Compose Android application ...

The Room persistence library provides an abstraction layer over SQLite. To use Room in your app, add the following dependencies to your app’s build.gradle file: dependencies { .... kapt "org.xerial:sqlite-jdbc:3.34.0" // Room def roo...

Model–View–ViewModel (MVVM) is a software architectural pattern that facilitates the separation of the development of the GUI (the view) from the development of the business logic or back-end logic (the model) so that the view is not dependent on any specific model platform. The ViewModel of MVVM is responsible for exposing the data objects from the model in such a way that objects are easily managed and presented. In this respect, the ViewModel is more model than view and handles most if not all of the view’s display logic. The ViewModel may implement a mediator pattern, organizing access to the back-end logic around the set of use cases supported by the view. I’ve put together a small sample showing these 3 layers and how they relate to each other in SwiftUI. You’ll notice that other than property/method names, none of the objects need to know anything about the others. Each layer can be built completely independent of the others.
import Foundation
struct User: Identifiable {
let id: UUID
let name: String
}
struct UserModel{
private(set) var users :[User] = []
mutating func addUser(_ user: User){
users.append(user)
}
}
We define a User model. The model has 2 members, a privately changeable users list and a mutating function to change the state of the user's collection. Note the User struct conforms to the Identifiable protocol. SwiftUI needs to know how it can identify each item uniquely otherwise it’s not able to compare view hierarchies to figure out what has changed when a new body is re-built in the view.
This should contain everything one would need to interact with the view. Right now it contains 2 members: users, and an addUser function.
import Foundation
import UIKit
class UserViewModel: ObservableObject{
@Published private var userModel = UserModel()
var users: [User] {
return userModel.users
}
func addUser(_ user: User){
userModel.addUser(user)
}
}
And now the View. These are DataTemplates that define how data should be displayed.
import SwiftUI
struct UserView: View {
@ObservedObject var viewModel = UserViewModel()
var body: some View {
NavigationView{
List(viewModel.users) { user in
VStack(alignment: .leading){
Text("\(user.name)")
Text("\(user.id)")
}
}
.navigationTitle("Users")
.toolbar {
Button(action: {
viewModel.addUser(User(id: UUID(),name: "User"))
}) {
Image(systemName: "plus")
}
}
.listStyle(PlainListStyle())
}
}
}
Anything that conforms to ObservableObject can be used inside SwiftUI, and publish announcements when its values have changed so the View can be updated. Clicking the add button will add User Objects to the collection which will cause the view to be rebuilt as shown here:
