Todolist Mvvm

Sample application using MVVM in Swift
Alternatives To Todolist Mvvm
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Gacui2,163
6 days ago15otherC++
GPU Accelerated C++ User Interface, with WYSIWYG developing tools, XML supports, built-in data binding and MVVM features.
Mvvmlight1,683
6 years ago14Java
A toolkit help to build Android MVVM Application
Loxodon Framework1,49576 days ago6July 11, 20221mitC#
An MVVM & Databinding framework that can use C# and Lua to develop games
Neutronium1,316385 months ago16September 11, 202092mitC#
🚀 Build .NET desktop applications using HTML, CSS and javascript.
Robobinding1,306726 years ago15June 13, 201635otherJava
A data-binding Presentation Model(MVVM) framework for the Android platform.
Mvvm_hacker_news887
6 years ago6Java
Android MVVM experiment project using the official Data Binding library
Iossampleapp666
2 months agomitSwift
Sample iOS app demonstrating Coordinators, Dependency Injection, MVVM, Binding
People Mvvm661
3 years agoJava
Sample created to practice MVVM and DataBinding in Android Applications.
Countries609
5 years ago4otherKotlin
An example Android app using Retrofit, Realm, Parceler, Dagger and the MVVM pattern with the data binding lib.
Android Mvvm437
5 years ago16apache-2.0Java
MVVM on Android using RxJava and Data Binding
Alternatives To Todolist Mvvm
Select To Compare


Alternative Project Comparisons
Readme

MVVM on iOS

MVC: Model-View-Controller

./img/mvc.png

  • Architectural design pattern
  • Developed by Xerox PARC in the 1970s
  • Expressed as a general concept in 1988

It’s an old concept

  • Which is not bad
  • Good ideas are improved upon over time

MVVM: Model-View-ViewModel

./img/mvvm.png

  • Developed by Microsoft, announced in 2005
  • A slight addition to MVC
  • We’ll discuss Data Binding later

Adds the ViewModel

“The central component of MVC, the model, captures the behavior of the application in terms of its problem domain, independent of the user interface.”

Wikipedia

(where *user interface* is the View and Controller)

The ViewModel captures the behaviors of an user interface in terms of general user interactions, independent of the view itself.

Why is this a good thing?

./img/massive-view-controller.png

  • Smaller view controllers!
  • Lower coupling
    • Decouples GUI code from presentation logic and state
  • Headless testing

View and ViewModel Relationship

  • Generally, one ViewModel per controller or UIView subclass:
    • UIViewController
    • UITableViewCell
    • UICollectionViewCell
    • etc.

Ownership

./img/mvvm.png

  • The View owns the ViewModel
    • ViewModels know nothing about Views
  • The ViewModel owns the Model
    • Models know nothing about ViewModels
  • The View knows nothing about the Model

Views do not communicate!

Views communicate with their ViewModels, which communicate with each other.

Problem

If the view’s state is stored in a ViewModel class, how do we keep the two in sync?

Data Binding

  • Not strictly necessary, but really helpful
    • Delegates can work here, but are more verbose
  • Helps keep ViewModel in sync with its View

1-way > 2-way

  • 2-way binding is really hard (it’s cyclical)
    • If 2-way binding seems like the only solution, find a better solution

ReactiveCocoa (RAC)

Popular and well-maintained

First released
2/26/2012
Last commit to master
11/3/2015 (at time of writing)
Stars
11,081
Contributors
129

Bond

  • A data binding framework
  • Less concept-heavy
  • Also well maintained
  • I am less familiar with it – examples will use RAC

Interlude: ReactiveCocoa

What is “Functional Reactive Programming”?

Functional reactive programming (FRP) is a programming paradigm for reactive programming (asynchronous dataflow programming) using the building blocks of functional programming (e.g. map, reduce, filter).

Signals

  • Represent streams of values (data) as they change
  • Signals can be observed
  • Two varieties in RAC: SignalProducer and Signal
  • Send events:
    • next: The data that the signal carries – can happen many times
    • error: An error occurred – terminates
    • interrupted: The signal was interrupted – terminates
    • completed: Successful completion – terminates

Signal Producers

func doNetworkStuff() -> SignalProducer<JSON, NoError>
let producer = doNetworkStuff()
producer.startWithNext { json in print(json) }
  • Has to be “started” to do anything
  • Kind of like promises
  • Network requests are a good example

Signals

  • Send values regardless of whether or not anything is observing
  • “Always On” semantics

Mutable Properties

let text = MutableProperty<String>("Hello, World!")
text.value // => "Hello, World!"
text.producer // => SignalProducer<String, NoError>
text.producer.startWithNext { s in print(s) } // prints "Hello, World!"
text.value = "Yo." // prints "Yo"
  • Exposes a SignalProducer of the values in the property

Binding

let (producer, observer) = SignalProducer<String, NoError>.buffer()
let text = MutableProperty<String>("")
text <~ producer
observer.sendNext("a")
text.value // "a"
observer.sendNext("b")
text.value // "b"
  • We can bind the result of a SignalProducer to a MutableProperty
  • The binding operator: <~
  • No KVO!

Actions

func saveTodoOnServer(todo: Todo) -> SignalProducer<Bool, NSError> {
    return SignalProducer(value: true)
}
let createTodo = Action { (t: Todo) -> SignalProducer<Bool, NSError> in
    return saveTodoOnServer(t)
}
let todo = Todo()
createTodo.values.observeNext { success in print(success) }
createTodo.apply(todo) // => SignalProducer<Bool, NSError>
createTodo.apply(todo).start() // prints "true"
createTodo.apply(todo).start() // prints "true"
  • Like a function, but where the result of invocation is observed rather than returned
    • Can have many observers!
  • Take parameters, return a SignalProducer
    • We apply parameters, and then start the resulting producer
    • Expose values property: A Signal of the values of the SignalProducer

A Sample Application: Todo List

ViewModels Drive the Application

protocol ViewModelServicesProtocol {

    var todo: TodoServiceProtocol { get }
    var date: DateServiceProtocol { get }

    func push(viewModel: ViewModelProtocol)
    func pop(viewModel: ViewModelProtocol)
}

protocol ViewModelProtocol {
    var services: ViewModelServicesProtocol { get }
}

Navigation

func push(viewModel: ViewModelProtocol)
func pop(viewModel: ViewModelProtocol)
  • ViewModels will instantiate and push other ViewModels.
  • Services are responsible for instantiating the proper Views.

Model Services

protocol TodoServiceProtocol {
    func update(todo: Todo) -> SignalProducer<Todo, NoError>
    func delete(todo: Todo) -> SignalProducer<Bool, NoError>
    func create(note: String, dueDate: NSDate) -> SignalProducer<Todo, NoError>
}
  • Model services deal with stateful resources, e.g. network operations
  • Only ViewModels have access to services

Views Observe ViewModels and React

class TodoTableViewModel: ViewModel, CreateTodoViewModelDelegate {
    let todos = MutableProperty<[TodoCellViewModel]>([])
    let deleteTodo: Action<(todos: [TodoCellViewModel], cell: TodoCellViewModel), NSIndexPath?, NoError>
}
class TodoTableViewController: ReactiveViewController<TodoTableViewModel> {
    override func viewDidLoad() {
        super.viewDidLoad()
        func removeRow(indexPath: NSIndexPath?) {
            todoTableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Left)
        }
        // Remove a row whenever a Todo is deleted
        viewModel.deleteTodo.values
            .filter { $0 != nil }
            .observeOn(UIScheduler())
            .observeNext(removeRow)
    }
}

Demo

The code: https://github.com/jalehman/todolist-mvvm

Inspiration & Credits

Mobile Makers

Thanks for letting me talk!

Popular Mvvm Projects
Popular Bindings Projects
Popular Software Architecture Categories

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Swift
Bindings
Mvvm
Viewmodel