top of page

Building a Todo List App with SwiftUI, MVVM, and Combine: Unleashing Your Inner Productivity Beast 🦁

Greetings, aspiring productivity wizards! In today’s thrilling adventure, we’ll be diving into the magical world of SwiftUI, MVVM, and Combine to conjure up a delightful Todo List app. Along the way, we’ll learn new spells, cast humorous incantations, and create an app that will help you tame the chaos in your life (or at least your tasks!). So, grab your wands, and let’s get started! 🧙‍♂️


This is what we r building today :)


The Foundations: SwiftUI, MVVM, and Combine 🏰


Before we start brewing our productivity potion, let’s get familiar with the ingredients:

  • SwiftUI: Apple’s shiny UI framework that allows us to create stunning user interfaces using Swift code.

  • MVVM (Model-View-ViewModel): An enchanting design pattern that helps us separate our UI (View) from our business logic (ViewModel), making our code more organized and reusable.

  • Combine: Apple’s mystical framework for processing asynchronous events, such as user inputs or network requests.

Now that we’re well-versed in the fundamentals, it’s time to conjure up our Todo List app!


Creating the Model: TodoItem ✨


Our first spell will be to create a simple TodoItem model:

import Foundation

struct TodoItem: Identifiable, Codable {
    let id = UUID()
    var title: String
    var isCompleted: Bool
}

This struct represents a single todo item, with a title and a flag indicating whether it’s completed. Simple, yet powerful! 💪


Brewing the ViewModel: TodoListViewModel 🧪


Next, we’ll concoct a TodoListViewModel to handle the business logic:

import Combine
import SwiftUI

class TodoListViewModel: ObservableObject {
    @Published var todoItems: [TodoItem] = []

    // More spells will be cast here soon!
}

Our ViewModel is an ObservableObject that holds an array of TodoItems. This array will be our source of truth for displaying and managing todo items.


Designing the View: TodoListView 🎨


Now, let’s weave our UI magic with SwiftUI:

import SwiftUI

struct TodoListView: View {
    @StateObject private var viewModel = TodoListViewModel()

    var body: some View {
        NavigationView {
            List {
                ForEach(viewModel.todoItems) { item in
                    HStack {
                        Text(item.title)
                        Spacer()
                        if item.isCompleted {
                            Image(systemName: "checkmark.circle.fill")
                                .foregroundColor(.green)
                        }
                    }
                }
                .onDelete(perform: viewModel.deleteTodoItem)
            }
            .navigationTitle("Todo List")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: viewModel.addTodoItem) {
                        Image(systemName: "plus")
                    }
                }
            }
        }
    }
}

Our TodoListView displays a list of todo items, a checkmark for completed tasks, and a "+" button to add new tasks. Simple, elegant, and functional! 🌟


Adding Spells to the ViewModel: TodoListViewModel 📜


Let’s go back to our TodoListViewModel and add some spells to manage the todo items:

// Add this to TodoListViewModel
func addTodoItem() {
    let newTodo = TodoItem(title: "New Task", isCompleted: false)
    todoItems.append(newTodo)
}

func deleteTodoItem(at offsets: IndexSet) {    todoItems.remove(atOffsets: offsets)
}

func toggleTodoItemCompletion(at index: Int) {
    todoItems[index].isCompleted.toggle()
}

With these spells added to our TodoListViewModel, we can now create, delete, and toggle the completion status of our todo items. 🧙‍♀️


Connecting the Dots: TodoListView and TodoListViewModel 🔗


Now, let’s update our TodoListView to call the appropriate ViewModel methods when needed:

ForEach(viewModel.todoItems.indices, id: \.self) { index in
    let item = viewModel.todoItems[index]
    HStack {
        Text(item.title)
        Spacer()
        Button(action: {
            viewModel.toggleTodoItemCompletion(at: index)
        }) {
            Image(systemName: item.isCompleted ? "checkmark.circle.fill" : "circle")
                .foregroundColor(item.isCompleted ? .green : .black) // Black emoji magic! 🖤
        }
        .buttonStyle(PlainButtonStyle())
    }
}

We made a slight change to the ForEach loop, iterating over the indices instead of the items. This way, we can call the toggleTodoItemCompletion(at:) method with the appropriate index. We also updated the checkmark button to show an empty circle for uncompleted tasks.

Add TodoListView() to ContentView to show view

Run it in Xcode!

import SwiftUI

struct ContentView: View {
    var body: some View {
        TodoListView()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

In Conclusion: Unleashing Your Inner Productivity Beast 🦁


Congratulations! We’ve successfully conjured up a Todo List app using SwiftUI, MVVM, and Combine. This magical combination not only makes our code clean and organized but also gives us an app to help tame the chaos of our daily lives.


So, go forth, share the knowledge, and let’s build a world of organized and productive developers, one todo list at a time! 🚀

Happy coding and organizing! 😄

5 views0 comments

コメント


bottom of page