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.
-
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
andclass
- 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 twoInt
s and returns aBool
-
(Double) -> Void
takes aDouble
and returns nothing -
() -> Array<String>
takes no arguments and returns anArray
andSting
s
-
- Functions as types
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
- Many options but we use mostly
Model
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
}
}
ViewModel
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> {
model.cards
}
// 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
View
(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
- Identifying happens by adding
Top comments (0)