CS193p Notes - Lecture 2: MVVM and the Swift Type System

lankinen profile image Lankinen ・4 min read

Model View ViewModel (MVVM)

  • A code organizing architectural design paradigm.
  • Imperative model calls functions between messing the UI in a way that it's hard to say what the code is going to exactly look like.
  • MVVM allows things like changing the UI right away when doing modifications because it's stateless. This is called reactive.
  • ViewModel is doing some stuff behind the scenes to use Model and not make View too complex.
  • Views are kind of like people inside a house, ViewModel is the door, and models are outside the house. This way View must go through ViewModel to access Models.

Alt Text

Alt Text

Alt Text

  • Types

    • struct
    • class
      • Struct and call are very similar
      • Stored vars (variables stored in memory)
      • Computer vars
        • var body: some View { return Text("hello world")
      • Constant lets
      • functions
        • function parameters can have two labels where the first is used outside the function (callers) and the second is used inside the function.
        • _ is same as no label
      • initializers
        • When created this can initialize some parameters.
      • Differences between struct and class
        • Struct is value type and class is reference type
        • Struct is kind of for functional programming while classes are more for OOP
        • Struct don't have inheritance
        • Struct has init that initialize all vars and that is why own initializer is done less often
        • Struct used mostly
    • protocol
    • "Don't care" type (aka generics)
      • Every variable has type
      • In some case we don't want to specify the type
        • For example we want array to contain all kinds of variables
      • Element is used when you don't want to use specific type
        • It's like placeholder and when later for example the array is used, it gets some value.
        • called Type Parameter
    • enum
    • Functions
      • Functions as types
        • (Int, Int) -> Bool takes two Ints and returns a Bool
        • (Double) -> Void takes a Double and returns nothing
        • () -> Array<String> takes no arguments and returns an Array and Stings
    var operation: (Double) -> Double
    func square(operand: Double) -> Double {
      return operand * operand
    operation = square
    let result1 = operation(4)
    operation = sqrt // built-in function which takes and returns a double
    let result2 = operation(4)
    • Closure
      • In-lining a function
      • more later...

  • File > New > File
    • Many options but we use mostly
      • SwiftUI View
        • UI file
      • Swift File
        • Non UI file
    • Save the file under yellow things not blue


import Foundation

struct MemoryGame<CardContent> {
        var cards: Array<Card>

    func choose(card: Card) {
        print("card chosen: \(card)")

    init(numberOfPairsOfCards: Int, cardContentFactory: (Int) -> CardContent) {
        cards = Array<Card>()
        for pairIndex in 0..<numberOfPairsOfCards {
            let content = cardContentFactory(pairIndex)
            cards.append(Card(isFaceUp: false, isMatched: false, content: content))
            cards.append(Card(isFaceUp: false, isMatched: false, content: content))

    struct Card {
        var isFaceUp: Bool
        var isMatched: Bool
        var contect: CardContent // placeholder type


import SwiftUI

class EmojiMemoryGame {
    private(set) var model: MemoryGame<String> = 
         MemoryGame<String>(numberOfPairsOfCards: 2, cardContentFactory: { pairIndex in "smile" })
    // ☝️ Only EmojiMemoryGame can modify the model but everyone can see it

    // MARK: - Access to the Model

    var cards: Array<MemoryGame<String>.Card> {

    // MARK: - Intent(s)

    func choose(card: MemoryGame<String>.Card) {
        model.choose(card: card)
  • This is class because multiple View can then use this same thing
  • MARK: - adds the comment to header in Xcode where it's easy to see them
  • The thing that comes after cardContentFactory is closure


(Done previously)

  • Static makes the function part of type not instance and that way it can be used in initialization
  • Hold option key down and click any word to see documentation
  • ForEach needs to be either iterable of ints or the items needs to be available to identify
    • Identifying happens by adding struct Name: Identifiable
    • Then it also requires a parameter id which can be any type


Originally published here

Posted on by:


Editor guide