Add a ViewModel with @EnvironmentObject in SwiftUI | Todo List #3

Swiftful Thinking
16 Mar 202140:53

Summary

TLDR在这段视频中,Nick 通过构建视图模型(ViewModel),向观众展示了如何在他们的应用程序中实现 MVVM(Model-View-ViewModel)架构。他首先解释了 ViewModel 在连接视图(UI 组件)和模型(数据点)之间的中心作用,然后逐步引导观众创建用于添加、读取、更新和删除数据的 ViewModel 类。Nick 还展示了如何在 SwiftUI 中实现列表的删除和移动功能,并将这些功能逻辑移至 ViewModel,以保持视图的简洁性。此外,他还介绍了如何通过环境对象在整个应用中共享 ViewModel,以及如何使用 `@StateObject` 属性包装器来观察 ViewModel 的变化。最后,Nick 通过添加新项、检查文本长度以及切换完成状态等功能,展示了如何在 ViewModel 中封装 CRUD(创建、读取、更新、删除)操作,强调了这种实践对于保持代码清晰和高效的重要性。

Takeaways

  • 📝 创建视图模型(ViewModel)是MVVM架构中的核心组件,它连接视图(View)和数据模型(Model)。
  • 🔄 ViewModel负责管理视图所需的数据,并通过模型来处理数据逻辑,如创建、读取、更新和删除数据。
  • 🎬 通过SwiftUI的ForEach循环,可以使用onDelete和onMove来实现列表项的删除和移动。
  • 🚀 将数据逻辑移动到ViewModel中,可以使得视图层(View)更加简洁,只负责UI界面的展示。
  • 📚 ViewModel使用`@Published`和`@StateObject`来确保数据变化时,视图能够自动更新。
  • 📦 通过创建环境对象(EnvironmentObject),可以在App的不同视图中共享ViewModel。
  • 🔗 使用`firstIndex(where:)`来查找数组中特定元素的索引,这是更新数据时常用的方法。
  • 🔧 在ItemModel中实现`updateCompletion`函数,用于更新项的状态,保持了数据模型的不可变性。
  • 🛠️ 遵循CRUD原则(创建、读取、更新、删除),在ViewModel中实现数据的基本操作。
  • 🔄 使用`withAnimation`为视图的交互添加动画效果,提升用户体验。
  • 📛 通过`Environment`和`presentationMode`来控制视图的导航和状态。
  • 🧩 在视图模型中封装所有数据逻辑,使得视图只关注UI展示,遵循MVVM的设计原则。

Q & A

  • 在Swift UI中,ViewModel的作用是什么?

    -ViewModel是MVVM架构中的核心组件,它连接视图(View)和数据模型(Model)。ViewModel负责存储和管理与视图相关的数据,以及包含创建、读取、更新和删除数据的逻辑。

  • 为什么在MVVM架构中需要分离视图和数据逻辑?

    -分离视图和数据逻辑可以使得代码更加模块化,易于维护和重用。视图仅负责UI展示,而数据逻辑则由ViewModel处理,这样可以提高代码的可读性和可测试性。

  • 如何在Swift UI中实现删除列表项的功能?

    -在Swift UI中,可以通过为List中的每个Item添加一个On Delete手势,来实现删除功能。在On Delete的perform方法中,调用删除数据的函数,并传入相应的Index Set作为参数。

  • 如何实现在Swift UI列表中移动项的功能?

    -在Swift UI中,可以通过为List中的每个Item添加一个On Move手势来实现移动功能。在On Move的perform方法中,调用移动数据的函数,并传入源索引集(Index Set)和目标偏移量(Integer)作为参数。

  • 为什么需要将数据和逻辑移动到ViewModel中?

    -将数据和逻辑移动到ViewModel中是为了遵循MVVM的设计原则,使得视图(View)只包含UI相关的代码,而所有的数据和业务逻辑都封装在ViewModel中,这样可以提高应用的架构清晰度和可维护性。

  • 如何在Swift UI中创建一个新的ViewModel?

    -在Swift UI中创建一个新的ViewModel,首先需要在项目导航器中创建一个新的Swift文件,并命名为ViewModel的名称,如`ListViewModel`。然后在该文件中定义一个类,使其符合`ObservableObject`协议,以便视图可以观察到ViewModel的变化。

  • 如何确保ViewModel在整个应用中被使用?

    -为了确保ViewModel在整个应用中被使用,可以将其作为环境对象(EnvironmentObject)嵌入到App的根视图中。这样,所有继承自根视图的子视图都能访问到这个ViewModel。

  • 如何在添加视图中实现添加新项的功能?

    -在添加视图中,可以通过创建一个按钮,并为其添加一个点击事件处理函数来实现添加新项的功能。在该函数中,首先检查输入的文本是否符合要求(如长度至少为3个字符),然后通过ViewModel将新项添加到数据数组中,并返回到前一个视图。

  • 如何实现在列表项被点击时切换其完成状态?

    -在列表项的ForEach循环中,可以为每个列表项添加一个On Tap Gesture手势。在该手势的处理函数中,调用ViewModel中的更新项的函数,并传入被点击的项,ViewModel会负责切换该项的完成状态。

  • 为什么在更新数据模型时使用不可变结构(Struct)?

    -使用不可变结构(Immutable Struct)可以确保数据模型的一致性和安全性。由于所有的属性都是常量(let),它们不能在Struct外部被修改,只能通过Struct提供的函数进行更新,这样可以避免数据不一致的问题。

  • 如何在Swift UI中实现数据的CRUD操作?

    -在Swift UI中实现CRUD操作,即创建(Create)、读取(Read)、更新(Update)、删除(Delete)。这通常通过ViewModel来完成,其中会包含相应的函数来处理数据的增加、查询、修改和删除逻辑。

Outlines

00:00

😀 构建视图模型 - MVVM架构的核心组件

Nick介绍了视图模型(ViewModel)是MVVM架构中的核心,它位于视图(View)和模型(Model)之间。视图模型负责连接视图和数据,处理数据的创建、读取、更新和删除逻辑。他强调了MVVM架构对于Swift UI开发者的重要性,并预告了视频中将涉及大量编码工作,但会逐步引导观众完成。

05:03

📚 视图模型与数据逻辑的分离

为了将视图与数据逻辑分离,Nick展示了如何将数据数组和删除、移动项的逻辑从视图中移至新创建的视图模型中。他解释了使用`@Published`变量和初始化函数(init)来添加模拟数据,并演示了如何将视图模型作为环境对象(Environment Object)在Swift UI中使用。

10:04

🔄 视图模型的可观察性与数据更新

Nick说明了如何通过使视图模型符合`ObservableObject`协议,来让视图能够观察数据的变化。他演示了在`ToDo ListApp.swift`文件中创建和初始化视图模型,并使用`@StateObject`属性包装器来观察它。此外,他展示了如何通过环境对象将视图模型传递给所有视图,从而实现数据的集中管理。

15:07

🧱 向视图模型添加添加项功能

为了实现添加新项的功能,Nick在视图模型中创建了`addItem`函数,该函数接收一个字符串类型的标题,并将其转换为`ItemModel`对象,然后添加到数据数组中。他进一步演示了如何在添加视图(Add View)中调用此函数,并通过`presentationMode`返回到列表视图。

20:08

🚫 输入验证和用户界面反馈

为了提高用户体验,Nick添加了文本输入验证,确保用户输入至少有三个字符才能添加新项。他还创建了一个警报(alert),当输入不满足条件时向用户显示提示信息。此外,Nick展示了如何使用Swift UI的`.alert`修饰符来实现这一交互。

25:10

🔄 切换待办项的完成状态

Nick介绍了如何通过`onTapGesture`和`withAnimation`在列表中切换待办项的完成状态。他展示了如何在视图模型中添加`updateItem`函数,并在`ItemModel`中实现更新逻辑,以保持数据的一致性和完整性。

30:10

📝 优化代码并遵循MVVM架构

为了遵循MVVM架构的最佳实践,Nick对代码进行了优化,将更新待办项逻辑的代码移至`ItemModel`中。他解释了使用不可变结构体(immutable struct)的好处,并演示了如何通过一个函数来更新待办项的状态,以确保数据的一致性和视图的更新。

35:11

🏁 完成MVVM架构并理解CRUD操作

在视频的最后,Nick总结了通过视图模型实现的CRUD(创建、读取、更新、删除)操作,强调了这些操作在处理数据时的重要性。他提醒观众,理解CRUD操作对于任何涉及数据的应用程序都是至关重要的。

Mindmap

Keywords

💡MVVM

MVVM是Model-View-ViewModel的缩写,是一种设计模式,用于构建和组织应用程序的用户界面。在视频中,MVVM是构建应用程序架构的核心,ViewModel作为连接用户界面(View)和数据模型(Model)的桥梁。

💡ViewModel

ViewModel是MVVM架构中的一个关键组件,负责存储和管理数据,以及处理与数据相关的业务逻辑。在视频中,创建ViewModel是为了将数据逻辑与用户界面分离,使得代码更加清晰和易于维护。

💡Swift UI

Swift UI是一个由苹果公司开发的用户界面工具包,允许开发者使用Swift语言创建用户界面。视频中提到Swift UI开发者,指的是使用Swift UI框架来设计和构建应用程序界面的开发者。

💡Environment Object

在Swift UI中,Environment Object是一种属性包装器,用于在应用程序的不同部分之间共享数据。在视频中,为了使所有视图都能访问到ViewModel,将其作为Environment Object添加到Navigation View中。

💡Observable Object

Observable Object是Swift UI中的一种协议,允许对象的状态被监听。当对象的状态发生变化时,任何依赖于该状态的视图都会自动更新。在视频中,ViewModel需要遵守Observable Object协议,以便其状态变化能够驱动UI更新。

💡CRUD

CRUD代表创建(Create)、读取(Read)、更新(Update)、删除(Delete),是数据管理中的基本操作。视频中提到,ViewModel中的所有数据操作函数都是CRUD操作的衍生,包括添加(Create)、获取(Read)、更新(Update)和删除(Delete)项目。

💡List

在视频中,List是Swift UI中的一个视图,用于显示一系列元素。开发者使用List来展示数据集合,如待办事项列表,并提供交互功能,如编辑、移动和删除列表项。

💡Data Array

数据数组是用于存储和管理数据集合的数据结构。在视频中,数据数组用于存储待办事项的模型对象,ViewModel中的操作函数对这些数据进行CRUD操作。

💡Item Model

Item Model是代表列表中单个条目的数据模型。在视频中,每个待办事项都是一个Item Model实例,包含了待办事项的标题、完成状态等信息。

💡Swift

Swift是一种由苹果公司开发的强类型、编译型编程语言,广泛用于iOS、macOS、watchOS和tvOS应用程序的开发。视频中提到的Swift指的是使用Swift语言进行编程和应用程序开发。

💡Xcode

Xcode是苹果公司开发的集成开发环境(IDE),用于开发macOS、iOS、watchOS和tvOS应用程序。视频中提到Xcode,是因为它是创建和编辑Swift UI应用程序的主要工具。

Highlights

在MVVM架构中,视图模型(ViewModel)是连接视图(View)和模型(Model)的核心组件。

视图模型负责管理视图所需的所有数据,并且包含创建、读取、更新和删除数据的逻辑。

通过视图模型,可以实现视图与数据逻辑的分离,提高代码的可维护性。

在SwiftUI中,可以使用`@State`和`@Published`属性包装器来观察对象变化,从而更新视图。

视图模型使用`init`函数初始化时,可以添加假数据以模拟真实应用中的数据。

通过将数据和逻辑移动到视图模型中,视图文件变得更加简洁,只包含UI相关的代码。

使用SwiftUI的环境对象(EnvironmentObject)可以在多个视图中共享视图模型。

视图模型需要遵循`ObservableObject`协议,以便在SwiftUI中被观察。

在添加新项目时,可以通过检查文本框的内容长度来限制用户输入,以确保数据的有效性。

使用`.alert`修饰符可以在SwiftUI中快速创建并显示警告信息。

在SwiftUI中,使用`.onTapGesture`可以为视图添加点击事件。

通过自定义模型的初始化器,可以保持模型的ID不变,同时更新其他属性。

在模型中封装更新逻辑,可以使数据更新更加集中和一致。

CRUD操作(创建、读取、更新、删除)是处理数据的基本函数,适用于大多数数据操作场景。

通过遵循MVVM架构和良好的编程实践,可以创建出结构清晰、易于维护的应用程序。

在SwiftUI开发中,理解并应用MVVM架构对于构建大型和复杂的应用程序至关重要。

Transcripts

play00:01

[Music]

play00:06

welcome back everyone i'm nick

play00:08

this is swiffle thinking and in this

play00:10

video we're gonna build the view model

play00:12

in our app

play00:13

and the view model is really like the

play00:15

bread and butter the main component of

play00:18

mvvm and that's because in mvvm

play00:21

on one side we have the view which is

play00:23

all of the ui components and we already

play00:25

did that

play00:26

on the other side we have the model and

play00:28

that's that's all of the data

play00:30

points in our app and then in the middle

play00:32

is the view model which we're going to

play00:34

build now

play00:35

and the view model is going to be

play00:36

connected to our view and it's going to

play00:38

hold

play00:38

all of the data for our views and that

play00:41

data of course

play00:42

is going to be a bunch of models that we

play00:45

made in the last video

play00:47

so in the view model is going to be all

play00:49

of the logic

play00:50

for creating reading updating

play00:53

and deleting data so it's going to be a

play00:56

lot of coding in this video

play00:57

it's probably going to be one of the

play00:58

harder videos but it's not going to be

play01:00

hard because i'm going to walk you

play01:01

through the whole thing

play01:02

so by the end of this video you will

play01:04

have successfully set up

play01:06

mvvm architecture in your first app so i

play01:09

hope you guys are excited because mvvm

play01:12

is

play01:13

such an important architecture to know

play01:15

as a swift ui developer

play01:17

and we have just effectively put it into

play01:19

our app

play01:20

in such a short amount of time and very

play01:22

efficiently so now you are an mvvm

play01:25

expert with that said let's start

play01:28

building our view model

play01:30

all right i am back in our xcode project

play01:33

i'm on the list

play01:34

view and before we actually create the

play01:38

view model

play01:39

let's create some functions as if we

play01:40

weren't going to use a view model

play01:43

just so you can see the difference so i

play01:45

want to add two functions to this list

play01:48

the first one is going to be for

play01:50

deleting items from the list

play01:52

and i did a whole video in the swift ui

play01:53

bootcamp on this so it should not be new

play01:56

but when you're in a list and you have a

play01:58

for each loop you can call at the bottom

play02:00

of the for each loop

play02:01

dot on delete and then there's a

play02:04

completion that says perform

play02:06

click enter on that and in here where

play02:08

this says code we can write a function

play02:10

to remove items from our data array so

play02:13

from this item's

play02:15

data at the top now of course we can put

play02:18

the function here and we can say items

play02:20

dot i believe it's remove at

play02:23

and there's a completion that has

play02:25

removed at offsets

play02:27

and the at offsets requires an index set

play02:31

and it just so happens that this on

play02:33

delete

play02:34

also gives us an index set for where we

play02:36

are swiping to delete

play02:38

so we can pass this index set into here

play02:42

i'm going to take this one step further

play02:43

and make it its own function so down

play02:45

here we'll call func

play02:46

delete item and we're going to pass in

play02:50

an

play02:50

index set so i'm going to say index set

play02:54

of type index set then i'm going to open

play02:57

the brackets

play02:58

and i'm going to take this items.remove

play03:00

i'm going to copy it i'm going to paste

play03:01

it into my

play03:02

new function and now we can just call

play03:05

this function

play03:06

from the on delete and because it is set

play03:09

up with just an index

play03:10

set we can actually delete all of this

play03:13

so from the start of this open brackets

play03:15

to the end of those open brackets

play03:17

and just add here delete item we click

play03:20

enter it will include that first

play03:22

parameter the index

play03:23

set which we said down here but we

play03:25

actually don't need this parameter

play03:26

because it's going to automatically

play03:27

connect to that parameter so

play03:29

we can just delete this and we have this

play03:32

super short super awesome

play03:34

on delete perform delete item

play03:37

if we click resume on the canvas

play03:40

press play on the live preview we should

play03:42

now be able to swipe

play03:44

to delete items so it was that easy

play03:48

and the next one we're going to do is on

play03:50

move so underneath on delete i'll call

play03:52

dot on move

play03:54

and again we have perform with indices

play03:56

and new offset

play03:58

so i'm going to create a function down

play03:59

here below delete item called func

play04:01

move item and this first indices

play04:04

is where it's coming from and the new

play04:06

offset is where it's going to

play04:07

so i'm going to make these parameters

play04:09

from

play04:11

of type so i'm going to hold the option

play04:13

button click on perform

play04:16

and we can see that the action here is

play04:18

giving us an optional

play04:20

index set so the indices is an index set

play04:23

and then new offset which is an integer

play04:25

so

play04:26

move item from index set

play04:30

to and this will be an integer

play04:34

open the brackets and there's another

play04:36

handy completion here we can call items

play04:37

which is our data array

play04:39

dot move and then of course from offsets

play04:42

will be our from and then two

play04:45

will be our two offsets so in here

play04:49

we can now delete this curly bracket

play04:51

section and just call

play04:53

move item and of course we can get rid

play04:55

of the

play04:56

parameters here and it's just nice and

play04:58

neat

play04:59

on delete delete item on move move item

play05:03

and if we click resume on the canvas and

play05:06

this is why we added that edit button

play05:08

in the previous video we can now click

play05:10

on the edit button

play05:11

it's going to go into editing mode and

play05:12

we can press these minuses on the left

play05:14

to delete items

play05:16

but we can also click and drag on these

play05:18

lines on the right

play05:19

to move items in our list so this is

play05:22

looking awesome

play05:24

click done when we're done editing and

play05:26

now let's start creating the view model

play05:29

and the reason we create a view model is

play05:30

to separate the view

play05:32

from the data logic so all the code in

play05:35

here is strictly for the view this is

play05:37

the ui

play05:38

code but this items array is has nothing

play05:41

to do with the actual

play05:42

view this is just the background data

play05:46

and this delete item in this move item

play05:47

also has nothing to do with the actual

play05:49

ui components it's just the background

play05:51

data

play05:52

so we're going to move all of this into

play05:53

our view model

play05:56

so let's start by right clicking on

play05:59

the navigator up here and i'm going to

play06:01

create a new group

play06:02

i'm going to call this view models

play06:06

i'm going to move it in between the

play06:08

models and the views

play06:10

so we kind of have three main folders

play06:12

here and i do that because

play06:14

the view model kind of connects the

play06:15

models to the views so i like to put it

play06:17

in the middle

play06:18

and we're going to right click on the

play06:20

view models create a new file

play06:23

and we're not going to need a swift ui

play06:25

preview here so we're just going to use

play06:26

a regular swift

play06:27

file double click it and

play06:30

let's call this list view model

play06:35

go ahead and click create and once we're

play06:38

inside let's create a class

play06:40

we're going to call it list view model

play06:43

and we're going to open the brackets

play06:46

now i'm going to open up two different

play06:48

screens on my screen here so i'm going

play06:50

to click this

play06:51

plus button on the right side which is

play06:53

the add editor on right

play06:56

and now we have two screens and right

play06:58

now they're both in the same file

play07:00

i'm going to click onto this right file

play07:02

here

play07:03

and then i'm going to go to the

play07:04

navigator and click on the list view

play07:07

and while i'm in this right side i'm

play07:09

going to then hide the canvas

play07:11

because we don't need it right now and

play07:13

now

play07:14

this really cool xcode function i can

play07:16

see two different files

play07:17

in my app so on the right we have our

play07:20

list view file and the left we have the

play07:22

list view model

play07:24

and the first thing we're going to do is

play07:26

take this items array and move it into

play07:28

the class here so if you follow the

play07:31

swift ui bootcamp you know that we

play07:32

cannot use the at

play07:34

state in a regular class we can only use

play07:36

add state when we're in a view

play07:38

so instead of at state we're going to

play07:40

use at published

play07:41

var and this is going to be an item's

play07:44

array we're going to call it items

play07:46

and it will be of type array of item

play07:49

model

play07:49

and for right now we'll set it equal to

play07:51

a blank array

play07:54

and when we go ahead and create this

play07:56

class

play07:57

it's going to call an init function so

play07:59

we're going to customize that init by

play08:00

adding init

play08:02

and we don't need any parameters here

play08:04

and in our init we then want to add some

play08:06

of this fake data to our array

play08:09

so i'm going to create a function to

play08:11

append items to this array

play08:12

so we'll call func get items

play08:16

open and close parentheses open the

play08:17

brackets

play08:19

i'm going to say let new items equals

play08:24

and i'm going to copy this whole array

play08:26

here so from this open brackets to this

play08:29

closing bracket here the square brackets

play08:32

i'm going to set new items equal to that

play08:34

array that we already had

play08:37

and then we're going to append these new

play08:38

items to this items array so we'll say

play08:42

items dot append contents of

play08:45

so if we were pending multiple items we

play08:47

need to do the contents of

play08:48

then we'll pass in new items

play08:52

so moving this over just to see it very

play08:54

quickly

play08:55

now in our knit we can call get items

play08:59

so when we create a listview model it's

play09:01

going to

play09:02

immediately on its initializer called

play09:04

get items get items is going to create

play09:06

these three fake models and then append

play09:08

them to our items array

play09:12

the next thing moving back into our list

play09:14

view here and i'm just going to hide

play09:16

this on the left here

play09:17

so on our list view we created those two

play09:19

functions delete item

play09:21

move item i'm going to copy those as

play09:23

well

play09:24

and i'm just going to paste them into

play09:26

our list view model

play09:29

these automatically compile and we don't

play09:31

have to edit them because it's now

play09:32

referencing

play09:33

this new items array that we already

play09:35

created

play09:36

so in a second we're going to delete

play09:37

them from our list view model

play09:40

and now the only problem we have is that

play09:43

we need to reference this list view

play09:44

model

play09:45

in our list view instead of typing this

play09:48

in directly

play09:50

so i'm going to x out of this view on

play09:52

the right by clicking this little x

play09:53

button here

play09:55

and open up the project navigator

play09:58

and we're going to make a list view

play10:00

model into an environment object

play10:02

which i did cover in the swift ui boot

play10:04

camp so you should be a little bit aware

play10:06

of what this is

play10:08

and this listview model is going to use

play10:09

throughout our entire app so i'm going

play10:11

to create it

play10:12

back at the beginning of our app in the

play10:14

to do listapp.swift file

play10:17

so in this file before we have the body

play10:20

i'm going to add a

play10:20

variable here i'm going to add a var and

play10:23

we'll call this list

play10:24

view model and i'm going to keep that l

play10:26

as lowercase because this is the

play10:28

variable

play10:29

it will be of type list view model which

play10:32

we just created

play10:33

and we're going to set it equal to a new

play10:35

list view model

play10:38

now if you followed the swifty bootcamp

play10:40

you know that

play10:42

if we want to observe this object so

play10:43

that if this object changes

play10:45

our views will actually update we need

play10:47

to add a property wrapper on this

play10:49

and when we create these classes on the

play10:51

initializer the best property wrapper to

play10:53

use is the at

play10:54

state object

play10:57

and when we do this we're going to get

play10:59

an error and i did this on purpose just

play11:01

to show you guys

play11:02

uh that this the listview model does not

play11:05

conform to observable object

play11:08

so now we need to do that and this is

play11:10

and this is awesome that xcode reminds

play11:12

us

play11:12

in case we ever forget so i'm going to

play11:14

right click on listviewmodel jump to

play11:16

definition

play11:17

so we go into the listview model and all

play11:19

we need to do is make it conform

play11:21

to observable object just do a colon

play11:25

observable object

play11:26

and now it conforms and now we can

play11:28

observe this class

play11:29

from our views i'm going to press the

play11:31

back button and go back to the to-do

play11:33

list app.swift

play11:35

i'm going to click command shift k to

play11:37

clean and rebuild

play11:39

and our error goes away and now that we

play11:42

have

play11:42

this state object here now we have this

play11:44

object we could pass it directly into

play11:47

the list view

play11:48

but even more efficient than that i'm

play11:49

going to just put it in the environment

play11:51

as an environment

play11:52

object so on the entire navigation view

play11:55

so that

play11:56

all the views within the navigation view

play11:57

have access to this

play11:59

i will add dot environment object

play12:02

and the object of course needs to be an

play12:04

observable object which is what we just

play12:05

made sure it was observable

play12:07

we'll pass in our list view model

play12:12

and now the list view as well as the ad

play12:15

view and all the other views have access

play12:17

to this listview model so if i

play12:20

jump into the list view

play12:25

i will click resume on the canvas just

play12:27

to make sure we're all connected still

play12:31

instead of this items we now have our

play12:33

environment object we can call at

play12:35

environment object

play12:39

var and i'm going to call it list view

play12:42

model

play12:43

of type list view model

play12:47

we can delete our items array because we

play12:49

don't need it because we're going to use

play12:50

the items that are in the model now so

play12:52

we'll delete this items array

play12:55

we will also delete our on our delete

play12:58

and move

play12:58

functions because now those functions

play13:00

are in our model

play13:02

so we'll delete these

play13:05

and we're getting an error message we

play13:07

cannot find the items array

play13:09

in scope and that's because we need to

play13:10

now access the model

play13:12

and then the items that are inside the

play13:14

model so we'll call

play13:16

list view model dot items

play13:20

that first error goes away and now it's

play13:22

also telling us that it can't find the

play13:24

delete item and that's because delete

play13:26

item is not

play13:27

just on our list view now it is in our

play13:29

list view model so we can call

play13:31

list view model dot delete item

play13:34

and again we don't need that parameter

play13:36

so that works

play13:38

and list view model dot move item

play13:41

all of our errors go away and you'll

play13:43

notice here immediately that

play13:44

we just have so much less logic in our

play13:47

list view like this is a very

play13:48

short view and that's because we moved

play13:51

all of the

play13:52

data references where we add data edit

play13:55

data

play13:55

into the view model so that all the

play13:58

logic that remains in our view here is

play14:01

strictly for the ui if i click resume on

play14:04

the canvas

play14:08

we're getting a crash and that's because

play14:10

the preview which is what the canvas is

play14:12

running

play14:13

doesn't have that environment object

play14:16

because that

play14:16

environment object is only being added

play14:18

when we actually run the app

play14:19

through our to-do list app.swift file so

play14:22

to fix that we can also just add

play14:24

an object into the preview so we'll call

play14:26

dot environment object

play14:28

and we'll add a new list view model

play14:32

open and close parentheses this is just

play14:34

initialize a new one and put it into the

play14:36

environment

play14:38

our preview now loads we can swipe to

play14:41

delete items still

play14:43

and of course we can edit and

play14:46

move items as well

play14:50

so all of our functions are running our

play14:51

logic is in our view model

play14:54

and there's a couple more functions i

play14:55

want to add before we finish this

play14:57

video the first one of course is being

play15:00

able to add an item to this

play15:02

so if we click the add button and we

play15:04

segue to our ad item view

play15:07

when we're here i want to be able to

play15:08

type something this

play15:10

is a new item and then click save and

play15:13

have it

play15:14

update on our list so let's jump into

play15:17

the ad view

play15:21

and we already have a button here so i'm

play15:22

gonna create a function that's gonna run

play15:24

when we click on this button so

play15:25

underneath the body

play15:27

i'll call funk and let's call

play15:30

save button pressed open and close

play15:34

parentheses

play15:34

open the brackets and because this is a

play15:38

function now we can get rid of these

play15:39

curly brackets in our action

play15:41

and just add save button pressed

play15:45

and now we're going to add some logic

play15:46

into our save button pressed

play15:48

and the first thing we want to do is

play15:49

append our new item

play15:51

to the data array and since our view

play15:54

model is in the environment we already

play15:56

have access to it in our ad view

play15:58

so at the top i'll call at environment

play16:01

object var list view

play16:05

model of type list view model

play16:10

now just like on the last screen the

play16:11

preview doesn't have access to it so we

play16:13

got to add one to the preview

play16:15

so down on the preview on the navigation

play16:17

view we'll add dot environment object

play16:20

a new list view model that will

play16:22

initialize

play16:24

and let's click resume on the canvas

play16:25

just to make sure it still builds

play16:30

and now when we add an item we're going

play16:32

to use the text that's in the text

play16:34

field and create a new item but all of

play16:38

that logic for creating a new item and

play16:40

adding it to the array i want to put

play16:41

into our list view model

play16:43

so i'm going to jump into the list view

play16:45

model

play16:47

we have delete item we have move item

play16:49

now let's create a funk

play16:50

add item and as i just mentioned when we

play16:54

add an item we're going to have the text

play16:55

already so we'll call it

play16:57

title of type string

play17:00

and we'll open the brackets and with

play17:03

this title we'll create a new item so

play17:05

we'll say let

play17:06

new item equals item model

play17:10

open the parentheses and the title will

play17:12

be title

play17:14

and is completed so since we're adding a

play17:16

new item is completed is going to be

play17:18

false to start so we did not complete it

play17:20

yet otherwise we wouldn't be putting it

play17:21

on our list

play17:22

and then we're just going to add this

play17:23

new item to our items array so we'll say

play17:26

items dot append new element and we'll

play17:29

add new item

play17:31

it's that simple let me go back into our

play17:35

add view

play17:36

i'm going to press command shift k to

play17:38

clean and rebuild

play17:40

again you can always click the product

play17:42

and clean build folder which is

play17:43

shift command k click resume

play17:48

and when save button is pressed we're

play17:50

going to call list view model

play17:53

dot add item and the title is going to

play17:56

be

play17:57

the text field text so text field

play18:00

text

play18:04

now after we click add item and we save

play18:06

that item

play18:07

i want to automatically pop out of this

play18:09

screen so it navigates back to our list

play18:12

to go back when we're in an environment

play18:15

or in a sheet

play18:16

we use that environment presentation

play18:18

mode so i covered this in the swift ui

play18:20

bootcamp as well

play18:22

at the top here we'll add at environment

play18:25

open the parentheses and we're going to

play18:27

use the key path

play18:28

the key path will be backslash dot

play18:30

presentation

play18:32

mode and this will be a variable called

play18:35

presentation mode and if you did this

play18:39

right

play18:39

this will turn purple so that you know

play18:41

it is connected

play18:42

and the presentation mode again is is

play18:45

something that comes by default on all

play18:46

of our screens in swift ui

play18:48

and it is just monitoring where we are

play18:51

in our view hierarchy

play18:52

so by using the presentation mode we can

play18:54

always basically tell it to go back one

play18:56

in our view hierarchy

play18:57

and that's what we're going to tell it

play18:59

right now so save button press we're

play19:01

going to call

play19:02

presentation mode which is our new

play19:04

variable we just created

play19:05

dot wrapped value dot dismiss

play19:09

and this looks a little ugly but all it

play19:11

does is tell the presentation mode

play19:13

to go back one in the in the view

play19:15

hierarchy

play19:18

so let's test this out quick so let's

play19:20

press run on the simulator

play19:29

simulator should pop up on your computer

play19:32

somewhere

play19:35

so we have our to-do list we can swipe

play19:37

to delete we can

play19:39

edit and move items but now let's try

play19:41

adding an item so we click add we go

play19:43

here

play19:44

let's say this is

play19:47

the new item i'm going to click save

play19:51

when we click save it should add the

play19:52

item to our data array

play19:54

and also navigate me back to the list so

play19:57

click save and boom it popped us back

play20:01

and we have our new this is the new item

play20:03

at the bottom of the list

play20:04

so this is working perfectly now while

play20:07

we're here there's a little bit of logic

play20:09

i want to add to this ad screen

play20:11

because if someone doesn't have anything

play20:13

typed here

play20:14

or if they only have like one letter

play20:16

typed i don't want them to be able to

play20:18

add items

play20:18

i want to do a quick little check to

play20:20

make sure they have at least like three

play20:22

or

play20:22

four characters in this text field in

play20:25

order to save a new item

play20:27

so let's do that quickly and i'm gonna

play20:31

hide the simulator quickly and where we

play20:34

have our save button pressed

play20:35

let's first check the text field text to

play20:38

make sure that it is long enough

play20:40

so i'm going to create a function to

play20:41

check the text so we'll create a new

play20:43

func

play20:44

we'll say funk text is appropriate

play20:49

open and close the parentheses and this

play20:51

is going to return

play20:53

which we use an arrow and then a bool

play20:55

open the brackets

play20:57

so if the text is appropriate it will

play20:58

return true

play21:00

if it's not appropriate it will turn

play21:02

false

play21:03

so we're gonna say if text field text

play21:07

dot count is less than three so if it's

play21:10

less than three characters long

play21:12

open the brackets and we will return

play21:14

false

play21:16

and if we return here it's going to

play21:18

return out of this function and never

play21:20

call the rest of this logic

play21:22

but if it gets the rest of this logic

play21:24

we'll just return

play21:25

true so if it's less than three it will

play21:27

return false if it's

play21:29

equal to or greater than three it will

play21:31

return true

play21:36

and now when we call save button pressed

play21:38

we're just going to add some logic here

play21:39

we're going to say

play21:40

if text is appropriate open brackets

play21:44

then we're going to put this logic

play21:46

inside these brackets

play21:49

so it's going to say if and then it's

play21:51

going to run this function this new text

play21:53

is appropriate function

play21:54

which is going to return true or false

play21:57

so if this

play21:58

function is equal to true then it's

play22:00

going to run

play22:01

all this logic but of course in swift we

play22:04

don't need this actual equals to true it

play22:06

just knows

play22:07

that this is saying the same thing as

play22:08

equal to true so if

play22:10

text is appropriate add item and go back

play22:15

and now the last thing i want to do here

play22:17

is if this is

play22:18

false because it's less than 3 i want to

play22:21

show an alert

play22:23

on the screens because right now if the

play22:25

user clicked save and it was less than

play22:26

three

play22:27

nothing would happen it would just look

play22:28

like the app wasn't working

play22:30

so instead i want something to pop up

play22:32

that says this should be at least three

play22:34

characters long

play22:35

so the user knows they need to keep

play22:38

typing

play22:40

so let's create an alert so at the top

play22:42

of our view here

play22:44

i'm going to add two variables for alert

play22:46

we'll do at

play22:48

state var alert title of type string

play22:52

we'll set it equal to a blank string for

play22:53

now and

play22:55

at state var show alert of type

play22:58

bool and we'll set it equal to false

play23:03

and now this is going to be the title

play23:05

that we want to show on the alert and

play23:06

this of course is going to be toggled

play23:07

when we want to show the alert

play23:09

so we could add this alert modifier

play23:11

anywhere in our view and it would work

play23:13

i'm just going to add it underneath the

play23:14

navigation title so we'll do

play23:16

dot alert and we're looking for the is

play23:19

presented completion and

play23:22

is presented of course we're going to

play23:23

bind it to our money sign

play23:25

show alert and for our content we could

play23:27

put it in here but i like to create

play23:29

functions just to keep our code clean

play23:31

so down at the bottom underneath text is

play23:33

appropriate we'll call funk

play23:35

get alert open and close parentheses and

play23:38

this is going to return

play23:40

an alert open the brackets

play23:43

and right now it's just going to return

play23:45

alert

play23:46

open the parentheses and we're just

play23:48

going to use the method with just a

play23:50

title

play23:51

the title requires a text so we'll type

play23:53

in a text

play23:55

and we need to add a string to the text

play23:58

and of course the title for our alert

play24:00

is going to be the variable we created

play24:01

at the top so we'll call alert

play24:03

title

play24:07

now when do we want to show this alert

play24:08

we want to show it when we

play24:10

fail this text is appropriate so right

play24:12

before we return

play24:13

false we're going to call show alert dot

play24:16

toggle

play24:18

and the last thing i want to make sure

play24:19

here is that before we show the alert we

play24:21

set that alert title so that it sets

play24:23

appropriately

play24:24

so before we call show alert i'm going

play24:26

to say alert title

play24:28

equals and let's set it to our alert

play24:30

message

play24:31

because we're failing this count right

play24:32

here of three characters let's say

play24:34

your new to do item

play24:38

must be at least three characters

play24:42

long and i'm going to press the ctrl

play24:45

command space

play24:46

to get the emojis and i love putting

play24:48

emojis in my code

play24:50

users usually love it too and let's use

play24:52

maybe uh

play24:54

one of these like worried emojis put a

play24:57

couple of them in because it might look

play24:58

cool

play25:02

so now our alert should be working and

play25:04

if this was your app

play25:05

you might have other checks you want to

play25:07

do here when the text is appropriate

play25:09

a lot of apps want to check for curse

play25:11

words so after

play25:12

this check you might have another check

play25:14

down here

play25:16

if there are curse words in your string

play25:17

and if there are curse words

play25:19

you would obviously change the alert

play25:20

title to you can't use curse words in

play25:22

your

play25:23

in your to-do item and then show alert

play25:25

as well

play25:27

but with what we have now we can put

play25:29

this get alert into our alert function

play25:31

so i'm going to remove these curly

play25:33

brackets here

play25:35

and just call get alert

play25:39

so this is nice and clean up here in our

play25:40

view

play25:42

and let's test this out and click run on

play25:44

the simulator one more time

play25:48

all right click the add and before we

play25:51

type anything in let's click save

play25:53

your new to do item must be at least

play25:55

three characters long so our alert is

play25:57

working

play25:58

and if we type in two characters hi

play26:01

we're still gonna get that error but

play26:03

once we have three characters i'm gonna

play26:04

do

play26:05

hii click save it now works and we

play26:09

append our new to do item to our to-do

play26:11

list

play26:12

so working perfectly and there is just

play26:15

one more function i want to do in our

play26:17

view model before we end this video

play26:19

and that's if i click on one of these

play26:21

rows

play26:22

i want to be able to toggle it or switch

play26:24

it between completed

play26:25

and not completed because right now if

play26:27

we do if we click on them

play26:29

we have no way of actually changing them

play26:31

from not completed to completed

play26:34

so let's do that real quick i'm gonna

play26:37

hide the simulator

play26:38

one more time all right so i'm gonna

play26:41

jump back into our list view

play26:44

and click resume on the canvas and on

play26:47

this list row view

play26:49

on one of these rows if i click on that

play26:51

row

play26:52

i want to toggle the completion between

play26:55

not completed and completed

play26:57

so on this whole list row view we'll

play26:59

just add an

play27:00

on tap gesture

play27:03

and when we do this i want to add some

play27:05

animation so that it animates

play27:07

from the current state to the next state

play27:08

so we'll do with animation

play27:11

and let's do dot linear which is just a

play27:14

kind of a seamless straight line

play27:15

animation

play27:16

and we'll open the brackets and now in

play27:18

this with animation we need to add some

play27:20

logic to

play27:21

update our item and so we have the item

play27:24

here that we're looping on in our for

play27:26

each

play27:26

but we don't have a function yet and as

play27:29

you're probably already guessing a great

play27:31

place to put that function is in our

play27:32

list view model

play27:34

so let's jump into the list view model

play27:36

i'm going to right click it jump into

play27:37

definition

play27:39

and we have delete we have move we have

play27:41

add and now let's add

play27:43

func update item

play27:46

and we're going to pass in the item that

play27:48

we clicked on so we'll say item

play27:50

of type item model we're going to open

play27:53

the brackets

play27:55

so we have this item already but we're

play27:58

going to need to

play27:59

figure out where this item is in our

play28:02

items array at the top here

play28:05

because we don't have the actual index

play28:07

for this item so first let's get the

play28:09

index

play28:09

so where this item that we clicked on is

play28:12

in our

play28:13

items array and to do that we're going

play28:15

to say

play28:16

i'm going to walk you through this

play28:17

quickly because some people might get

play28:19

confused

play28:20

so first let's say let index equals

play28:24

items which is our items array dot first

play28:28

index where

play28:32

and this is going to find the first

play28:34

index

play28:35

and we know the first index is the same

play28:37

as the only index because all these

play28:38

items are unique

play28:40

so first index where and let's click

play28:43

enter on this completion so this is

play28:46

going to loop through our array

play28:48

and for each of the existing items in

play28:50

the array so that's what this

play28:51

is here so this will be existing item

play28:54

we want to return the first case where

play28:58

the existing item's id

play28:59

is the same as this item's id so in here

play29:02

we will return

play29:05

existing item dot id is

play29:09

is equal to item dot id

play29:14

so this index is going to basically be

play29:16

the first index where

play29:18

an item in your items array has the same

play29:21

id

play29:22

as the item that we are looking for and

play29:24

we know that's going to be the same item

play29:26

and if we hold the option button and

play29:28

click on first index

play29:30

we'll see that this returns an optional

play29:32

integer if we click on

play29:34

hold the index option button and click

play29:36

on the index here

play29:38

we'll see that it is optional with the

play29:40

question mark and it's optional because

play29:42

in case there's a situation where we try

play29:44

to get this first index and there is no

play29:46

item with the same id

play29:49

then it will return nil but of course we

play29:51

know this is going to be true and we

play29:53

want to

play29:54

safely unwrap this index so instead of

play29:57

just using a

play29:58

let statement here we can say if let

play30:02

and then we will open the brackets

play30:03

afterwards so if this index is true

play30:06

we will run this code

play30:10

and now i wanted to walk you through

play30:11

this because this is super powerful

play30:13

but there's actually a shorter way to

play30:15

write this bit of logic here

play30:17

so let's do that down here and this is

play30:19

just good practice

play30:21

so this time let's just do if let index

play30:23

equals items

play30:25

dot first index where

play30:28

and then in this instead of pressing

play30:30

enter we're gonna open

play30:32

the brackets here and press space

play30:36

and in here we will do the money sign

play30:39

zero dot id and this money sign

play30:43

zero is what we're looping on so it's

play30:44

the same thing as this existing item

play30:46

here

play30:47

and we'll just set the existing item

play30:49

equal to

play30:50

item dot id and then we can open the

play30:54

brackets

play30:55

so this line of code is the exact same

play30:58

as these three lines of code

play31:00

but it's just a little shorter to write

play31:02

this and if you're working on like a

play31:04

team with other professionals they're

play31:06

probably gonna end up writing it like

play31:07

this

play31:08

just because it is quicker to read it's

play31:09

quicker to write

play31:11

so we actually don't need this code

play31:12

anymore i'm going to just

play31:14

highlight it press the command and

play31:16

backslash to comment it out

play31:19

just wanted to show you guys that and

play31:20

now now that we have this new index

play31:23

we just want to update the item at the

play31:25

index so what we're going to do is

play31:28

call items and we're going to access

play31:30

that index by using the brackets

play31:32

the index so this refers to the item at

play31:35

that index

play31:36

and we're just going to set it equal to

play31:38

a new item model

play31:40

open the parenthesis and this new item

play31:43

model is going to have the same title as

play31:45

the

play31:46

current item model but a different

play31:48

completed status

play31:50

so we'll call item dot title

play31:53

and is completed will be item dot

play31:56

completed and then we're just going to

play31:57

use the

play31:58

not sign so print an exclamation point

play32:00

before it so it's the opposite of the

play32:02

item.completed

play32:04

and now there's something happening

play32:05

behind the scenes here that you might

play32:06

not have realized

play32:08

but when we create a new item model

play32:10

every time we create a new item model

play32:12

it creates a new id so if we set this

play32:15

index equal to this new item model

play32:17

it's actually not the same as this item

play32:20

so it's actually going to be a

play32:21

new item model with a new id but what we

play32:25

really want is the same

play32:26

item models id just with the new is

play32:29

completed

play32:30

so we need to fix the initializer in our

play32:32

item model and when we go to do that

play32:35

it's also going to be more convenient to

play32:37

include all the logic

play32:38

for updating and changing these item

play32:41

models within the item model itself

play32:44

so that if we ever need to update item

play32:46

model from anywhere else in our app

play32:48

we don't do it from our view model we do

play32:50

we update the item model directly from

play32:53

the item model and that's good practice

play32:55

and

play32:56

in line with mvvm architecture as well

play32:59

so this logic here we're going to get

play33:01

rid of in a second

play33:03

so let's just right click the item model

play33:05

jump to definition

play33:06

so we go into our item model screen here

play33:09

and

play33:10

as i mentioned when we create a new item

play33:11

model right now it creates a new

play33:14

uuid string every time but let's

play33:16

customize this initializer so that if we

play33:19

have the id

play33:19

already it doesn't create a new one so

play33:22

right now the init looks like this we'll

play33:24

do init

play33:25

and it looks like title of type string

play33:29

is completed of type pool

play33:33

and open the brackets and right now

play33:36

what's happening

play33:36

it's really calling self.id which is

play33:40

this variable here equals uuid

play33:44

dot string self.title equals

play33:47

title self dot is completed eagles is

play33:50

completed

play33:51

so this is what we just saw before this

play33:53

is the current initializer that we're

play33:55

using

play33:56

what we're going to do is customize it

play33:58

so that we can optionally add an id in

play34:00

here

play34:01

and the first thing we're going to do is

play34:02

get rid of this string so instead of

play34:03

setting it up here

play34:04

automatically we're going to set it

play34:05

through the initializer

play34:09

and now i want to pass in an id into our

play34:12

knit as well so we'll do id

play34:14

of type string and then make that as new

play34:18

parameter

play34:20

i want to reference this id but i also

play34:22

want to include a default case so that

play34:24

if we don't have a string here

play34:26

we can still initialize this variable by

play34:29

using a random id string

play34:31

so i'm going to make the id of type

play34:33

string but we're going to also

play34:34

set it equal to uuid dot

play34:38

uuid string and here we're going to call

play34:41

id so that we reference this id so

play34:45

with this parameter in here we basically

play34:49

can

play34:49

initialize an item model with an id

play34:52

if we give it a string or without an id

play34:56

and it will automatically create one

play34:57

so anywhere in my app if i call item

play35:00

model

play35:00

open the parentheses i have two

play35:02

different initializers here

play35:04

one where i want to add the id directly

play35:07

and then another item model

play35:08

one where i don't have an option of

play35:10

adding an id and it will automatically

play35:12

create the id

play35:13

for us so this first item model we're

play35:16

going to use

play35:16

when we create new items and this second

play35:19

one with the id we're going to use when

play35:21

we update items because we already have

play35:23

an id

play35:24

let's delete these the last thing i want

play35:27

to do here is put a function within our

play35:29

item model

play35:30

so that we can update the item model

play35:33

so let's create a func update completion

play35:37

open close parenthesis and this is going

play35:38

to return an item

play35:40

model and open the brackets

play35:44

and we're going to return of course item

play35:46

model open the parentheses

play35:48

and we're going to use the id title and

play35:50

is completed

play35:52

so this will be called from within an

play35:54

item model so we already have an item

play35:56

model

play35:57

and then on that existing model we're

play35:59

going to call update completed

play36:01

so when we do this we're going to call

play36:03

we're going to create a new item model

play36:05

but we want to use the same id

play36:06

so now in here we're going to reference

play36:09

the current id that's in the item model

play36:11

that we're inside

play36:12

so we'll pass in id which is this id

play36:15

here

play36:16

the title is going to stay the same so

play36:17

we'll pass in the title which is here

play36:19

and then we want to do the opposite of

play36:21

the current is completed so we're going

play36:22

to do

play36:23

exclamation point for not is completed

play36:27

and something i haven't really touched

play36:29

on but you can google

play36:31

this struct is called an immutable

play36:33

struct so i'll type in here immutable

play36:36

struct and it is a very common pretty

play36:39

good practice a lot of developers will

play36:40

recommend it

play36:41

when you create these structs all of

play36:43

these items are let

play36:45

items and because they're not variable

play36:47

that means they will never

play36:48

change and the reason we do that is

play36:50

because if it's not immutable and these

play36:53

were

play36:53

var there would be a bunch of cases

play36:56

where you could change this title

play36:57

directly you could change it from the

play36:59

view model you could change it from

play37:00

somewhere else

play37:02

and if you did that there might be a

play37:04

case like on accident

play37:05

where the title is different from where

play37:08

it actually is maybe in your database or

play37:09

something like that

play37:11

so by creating an immutable struct and

play37:13

creating these all as

play37:14

let constants they cannot just change on

play37:16

the fly

play37:18

and that's why we're updating our struct

play37:19

here only through this function down

play37:21

here

play37:22

so we can never change any of these

play37:24

items or any of these

play37:26

variables unless it's through this

play37:28

function and this way we can make sure

play37:30

that

play37:30

all of the logic in our app that refers

play37:33

to updating and model

play37:35

is just within this function keeping it

play37:38

clean

play37:38

and efficient let's now call this update

play37:41

completion

play37:42

back in our code so i'm going to go to

play37:44

the list view model

play37:48

and let's press command shift command k

play37:50

to clean and rebuild

play37:51

i'm going to delete this item model here

play37:53

because we

play37:54

we now know that we do not update items

play37:58

outside of the item model we only do it

play37:59

within an item model

play38:01

so what we're going to do we're going to

play38:02

set this equal to our current item which

play38:04

is item

play38:05

dot update completion

play38:09

this is going to handle all the logic

play38:11

for updating that item for us

play38:13

all right this is looking good i'm going

play38:15

to delete this code here you can keep it

play38:16

in your code if you want to just

play38:18

reference it

play38:20

this is looking clean this is looking

play38:22

concise and let's put this update item

play38:24

back into our code so let's jump into

play38:26

the list view

play38:28

with animation we're going to call list

play38:30

view model dot

play38:32

update item and we're going to pass in

play38:34

our item

play38:37

and let's run the simulator one more

play38:39

time for this video and see if it works

play38:44

we have our items and now if we click it

play38:47

boom

play38:48

it's completed and we can toggle all

play38:51

these

play38:51

so easily so well we did it with super

play38:54

efficient code

play38:56

we can add new items this is

play38:59

my item and we can toggle them

play39:03

we can then edit and move them and of

play39:06

course we can

play39:07

delete them we added a view model to our

play39:11

app

play39:12

and in the view model we handled all the

play39:14

logic for

play39:15

updating moving adding deleting items

play39:19

and for those of you who are wondering

play39:21

why we added these four functions it's

play39:23

because

play39:23

these are the crud functions so i'm

play39:26

going to add at the top here a little

play39:27

bit of comment here

play39:29

let's do a multi-line comment with crud

play39:32

functions and basically anytime you're

play39:35

dealing with data

play39:36

all of the functions in your app are

play39:38

going to derive they're going to be

play39:39

derivatives of

play39:40

the four crud functions and crud stands

play39:43

for

play39:43

create read update

play39:47

delete so all functions for your data

play39:50

are going to derive from these four

play39:52

so in our app we now have a function to

play39:54

add items which is creating a new

play39:56

item we have a function to get items

play39:58

which is

play39:59

reading items we have a function to

play40:01

update the item so we toggle the item's

play40:03

completion

play40:04

and we have a function to delete the

play40:06

item if we want to swipe to delete that

play40:09

item

play40:10

and this is the same for if you had

play40:11

users in your app you could create a

play40:13

user profile you would read and get that

play40:15

user's information

play40:17

update a user's profile and then delete

play40:18

a user's profile

play40:20

so anytime you're learning and you're

play40:21

dealing with that data a good thing to

play40:23

benchmark would be to just make sure

play40:25

that you

play40:26

can understand and know how to create

play40:29

all four of these types of functions

play40:30

with your data

play40:32

all right guys i'm done rambling sorry

play40:35

this was another longer video but we

play40:36

covered a lot of really good juicy stuff

play40:38

hope you enjoyed it as always i'm nick

play40:41

this is swiffle thinking

play40:43

and i will see you in the next video

play40:52

you

Rate This

5.0 / 5 (0 votes)

Related Tags
Swift UIMVVM视图模型数据管理增删改查编程教程iOS开发Xcode项目用户界面后台逻辑CRUD函数
Do you need a summary in English?