0
1
00:00:00,510 --> 00:00:00,880
All right.
1

2
00:00:00,910 --> 00:00:03,010
So how did that go?
2

3
00:00:03,010 --> 00:00:04,180
I hope you gave it a go.
3

4
00:00:04,300 --> 00:00:10,340
And you now have a working CategoryViewController that works as you expect it to.
4

5
00:00:10,390 --> 00:00:14,970
Now, I know I'm repeating myself, but if you haven't given it a go, do it now.
5

6
00:00:15,130 --> 00:00:20,290
Don't watch the solution video first, because then you can't prove to yourself that you really do understand
6

7
00:00:20,290 --> 00:00:20,800
it.
7

8
00:00:20,890 --> 00:00:26,170
So I'm going to presume that you've given it a real good go and you're just here to check and make sure
8

9
00:00:26,170 --> 00:00:27,220
that you've got it right.
9

10
00:00:27,220 --> 00:00:33,880
So if we have a look at our To Do list view controller, the first thing we have is this variable itemArray
10

11
00:00:33,880 --> 00:00:39,190
that contains an array of NSManagedObjects created using the item entity.
11

12
00:00:39,220 --> 00:00:41,320
Now, over here, we'll need something similar.
12

13
00:00:41,440 --> 00:00:50,960
So let's create a variable called categories that is going to be an array of Category objects, and we'll
13

14
00:00:50,980 --> 00:00:53,630
initialize it as an empty array.
14

15
00:00:53,710 --> 00:00:59,980
The next thing we need to do is we need to grab a reference to the context that we're going to be using
15

16
00:01:00,340 --> 00:01:04,570
in order to create, read, update, and destroy our data
16

17
00:01:04,570 --> 00:01:09,740
and this is gonna be the thing that's going to communicate with our persistent container.
17

18
00:01:09,790 --> 00:01:16,390
So the context is going to be equal to our UIApplication and we're going to grab the shared singleton
18

19
00:01:16,390 --> 00:01:22,990
app instance, and we're going to tap into its delegate property, and we're going to downcast this as
19

20
00:01:23,080 --> 00:01:31,720
a AppDelegate object, and then we're going to tap into our appDelegates persistentContainer variable,
20

21
00:01:31,840 --> 00:01:36,880
and then we're going to load up the viewContext for that persistentContainer.
21

22
00:01:37,060 --> 00:01:39,820
If any of that was confusing at all,
22

23
00:01:39,820 --> 00:01:45,310
make sure that you have a look back at when we first wrote this line of code, and also the animations
23

24
00:01:45,310 --> 00:01:47,190
where we walk through how this worked.
24

25
00:01:47,200 --> 00:01:51,010
Now, the next thing is to setup our TableView Datasource Methods,
25

26
00:01:51,010 --> 00:01:52,920
so we should know the required ones by now,
26

27
00:01:52,920 --> 00:01:53,360
right?
27

28
00:01:53,380 --> 00:01:59,960
It's table view numberOfRowsInSection and we're going to return,
28

29
00:02:00,100 --> 00:02:02,910
of course, the number of items in our categories array.
29

30
00:02:02,980 --> 00:02:07,820
So return categories.count.
30

31
00:02:07,900 --> 00:02:08,200
All right.
31

32
00:02:08,230 --> 00:02:17,800
So onto the next obligatory table view delegate method which is tableView cellForRowAt indexPath
32

33
00:02:18,010 --> 00:02:21,990
which is here, cellForRowAt indexPath.
33

34
00:02:22,030 --> 00:02:24,550
So here we are going to--
34

35
00:02:24,580 --> 00:02:31,660
So here we are going to dequeue a ReusableCell withIdentifier for indexPath.
35

36
00:02:31,660 --> 00:02:36,010
So this creates a reusable cell and adds it to the table at the index path.
36

37
00:02:36,040 --> 00:02:42,520
So the identifier is a string. And let's just go back and check what we called it and we called it 
37

38
00:02:42,520 --> 00:02:42,960
CategoryCell.
38

39
00:02:43,320 --> 00:02:49,810
So I'm just gonna copy and paste it into here as the identifer and the index path is, of course, the current
39

40
00:02:49,810 --> 00:02:53,120
indexPath that the table view is trying to load up.
40

41
00:02:53,200 --> 00:02:59,290
Now, once we've created our reusable cell-- Now, once we've created our reusable cell, we got to set the
41

42
00:02:59,290 --> 00:03:08,170
cell's textLabel.text property and we're gonna set it to equal categories at indexPath.row,
42

43
00:03:08,200 --> 00:03:15,820
and we're going to tap into the category's name property or name attribute that we created earlier on.
43

44
00:03:15,820 --> 00:03:21,380
That property gets automatically generated because we added it as an attribute.
44

45
00:03:21,910 --> 00:03:29,210
And finally all that's left to do is to simply return the cell, and it will be rendered on screen.
45

46
00:03:29,350 --> 00:03:35,320
Now, the next thing I'm going to work on is the addButtonPressed IBAction, and here we're going to
46

47
00:03:35,320 --> 00:03:43,730
create a new alert which is going to be created from a UIAlertController and I'm gonna use the initializer
47

48
00:03:43,750 --> 00:03:53,350
that takes a title which we'll call "Add New Category," message, we'll leave blank, and the preferred style
48

49
00:03:53,350 --> 00:04:00,500
will just be alert. And then I'm going to create a action = UIAlertAction.
49

50
00:04:00,640 --> 00:04:07,910
And this also takes a title which is going to be the word just "Add." That's gonna be the name of the button.
50

51
00:04:07,990 --> 00:04:12,850
The style is just going to be default action and I'm going gonna select the placeholder for the handler
51

52
00:04:12,940 --> 00:04:17,350
and hit enter so that it creates this completion handler for us.
52

53
00:04:17,350 --> 00:04:20,170
I'm going to name the alert action just action.
53

54
00:04:20,170 --> 00:04:23,790
We're not really going to use it. And I'm going to delete the code placeholder.
54

55
00:04:23,890 --> 00:04:30,460
Now, inside this completion block or closure is where we're going to specify what should happen once
55

56
00:04:30,460 --> 00:04:32,580
the user clicks that add button.
56

57
00:04:32,650 --> 00:04:39,370
But before we do that, we're going to say alert.addAction and the action we want to add is the one
57

58
00:04:39,370 --> 00:04:40,770
that we created just now.
58

59
00:04:40,870 --> 00:04:48,100
And we're also going to setup our text field. So we do that using alert.addTextField, and we're
59

60
00:04:48,100 --> 00:04:54,220
going to hit enter on the configuration handler, and we're going to call our text field just field.
60

61
00:04:54,220 --> 00:05:00,470
And once that new text field has been created and added to the alert, we're going to store a reference to it
61

62
00:05:00,770 --> 00:05:09,560
by creating a variable called textField which is going to be a new UITextField object, and then we're
62

63
00:05:09,560 --> 00:05:17,870
going to set that textField to be equal to the field that is created inside our alert. And then we're
63

64
00:05:17,870 --> 00:05:26,120
going to set the textfield's placeholder to maybe something like "Add a new category."
64

65
00:05:26,120 --> 00:05:33,430
And finally, we're going to say present, view controller to present is the alert view controller, animated:
65

66
00:05:33,490 --> 00:05:37,060
true, completion: nil.
66

67
00:05:37,240 --> 00:05:37,610
Okay.
67

68
00:05:37,610 --> 00:05:45,560
So, now it's time to address what should happen when the user clicks on the Add button inside the alert.
68

69
00:05:45,560 --> 00:05:51,410
Well, this is where we have to create a new NSManagedObject and that is going to be a new category.
69

70
00:05:51,440 --> 00:05:53,120
So let
70

71
00:05:53,120 --> 00:05:57,260
newCategory = category.
71

72
00:05:57,260 --> 00:06:04,230
Now, notice how this also a type alias called OpaquePointer that also has the name category.
72

73
00:06:04,250 --> 00:06:11,090
So make sure you don't pick the OpaquePointer, pick our category instead, and also double-check the data
73

74
00:06:11,090 --> 00:06:15,790
type by option clicking on category afterwards.
74

75
00:06:16,040 --> 00:06:22,760
And we have to create our category by specifying a context. We've already created a reference to our
75

76
00:06:22,760 --> 00:06:25,110
context at the top of our file.
76

77
00:06:25,160 --> 00:06:27,590
So that's the one we're going to use.
77

78
00:06:27,590 --> 00:06:35,360
And by the way, if when you option-click on your category and Xcode tells you it's a OpaquePointer data
78

79
00:06:35,390 --> 00:06:39,500
type, just surround the word 'Category' with backticks like this,
79

80
00:06:39,650 --> 00:06:45,540
and that should solve the problem. But because we're inside a closure, remember, we have to write
80

81
00:06:45,630 --> 00:06:53,470
self.context in order to refer to that variable. Now, we're going to set up the new category, newCategory.name
81

82
00:06:53,470 --> 00:06:58,000
is going to equal to the 
82

83
00:06:58,000 --> 00:06:59,860
textField.text
83

84
00:06:59,860 --> 00:07:06,000
So whatever the user entered into that textField inside the alert is gonna be the name of the new category.
84

85
00:07:06,100 --> 00:07:16,180
And then we're going to grab a reference to our array of category objects by saying
85

86
00:07:16,840 --> 00:07:18,500
self.categories.append,
86

87
00:07:18,600 --> 00:07:22,080
and we're going to add this newCategory to the array.
87

88
00:07:22,210 --> 00:07:25,810
And finally, we're going to call saveCategories.
88

89
00:07:25,810 --> 00:07:30,500
And this method, of course, doesn't exist which is why it's not being highlighted.
89

90
00:07:30,520 --> 00:07:38,050
So this is a good time to go into our Data Manipulation Methods section over in the middle here and
90

91
00:07:38,170 --> 00:07:44,020
add that function saveCategories.
91

92
00:07:44,550 --> 00:07:49,920
And now Xcode reminds us that, of course, we need the "self" in front of saveCategories because we're
92

93
00:07:49,920 --> 00:07:50,760
inside a closure,
93

94
00:07:51,120 --> 00:07:55,680
and then it changes color to reflect the fact that it recognizes what we're talking about and which
94

95
00:07:55,680 --> 00:07:57,410
method we want to use.
95

96
00:07:57,420 --> 00:08:07,410
So inside our saveCategories method, I'm going to try and commit our context to our persistent container
96

97
00:08:07,440 --> 00:08:15,990
by saying context.save. Now, because this throws, then I'm going to hold it inside a do catch block
97

98
00:08:16,620 --> 00:08:31,820
and I'm going to log or print any errors that it catches, so "Error saving category" and the error is error.
98

99
00:08:31,910 --> 00:08:32,690
All right.
99

100
00:08:32,690 --> 00:08:39,490
And finally, once we have saved successfully, we're going to call tableView.reloadData so that our
100

101
00:08:39,530 --> 00:08:42,920
table view updates with our latest data.
101

102
00:08:42,920 --> 00:08:51,290
Now, the last thing that we have to do is we need to call a method called loadCategories
102

103
00:08:51,290 --> 00:08:57,410
when we first initialize our CategoryViewController. and that also does not exist,
103

104
00:08:57,410 --> 00:09:02,540
so we need to add that over here. I'm gonna create a function called loadCategories.
104

105
00:09:04,900 --> 00:09:11,400
And inside here, we need to read data from our context. And to read data from our context,
105

106
00:09:11,410 --> 00:09:19,930
we need to specify a request and we need to specify the data type of the request as a NSFetchRequest
106

107
00:09:19,930 --> 00:09:24,620
that is going to return an array of category items.
107

108
00:09:24,940 --> 00:09:28,060
And this is going to be equal to a broad request,
108

109
00:09:28,060 --> 00:09:30,880
so we want to grab all of the category objects.
109

110
00:09:30,880 --> 00:09:39,340
So we're going to say Category.fetchRequest, so we get back all the NSManagedObjects that were
110

111
00:09:39,340 --> 00:09:41,480
created using the category entity.
111

112
00:09:41,800 --> 00:09:51,160
So now we're going to say try context.fetch and we're going to fetch back all the results that fit
112

113
00:09:51,400 --> 00:09:52,800
our current request.
113

114
00:09:52,870 --> 00:10:01,030
And if our fetching of our requests succeeds, then we're going to save the output or whatever gets returned
114

115
00:10:01,090 --> 00:10:04,260
from this method into our categories array.
115

116
00:10:04,990 --> 00:10:13,230
So we can say categories = try context.fetch(request). And because this method can throw, then it's
116

117
00:10:13,240 --> 00:10:22,660
a good idea to trap it inside a do catch block where we're going to print and say there was an 
117

118
00:10:22,780 --> 00:10:32,900
"Error loading categories" and this was the error code, an error message. So, now all we have left to do is we
118

119
00:10:32,900 --> 00:10:40,190
have to tell the tableView to reload the data using our latest version of categories after fetching
119

120
00:10:40,340 --> 00:10:41,730
all of the category object.
120

121
00:10:41,750 --> 00:10:47,560
So let's give our app a go and see if all of that code works.
121

122
00:10:47,750 --> 00:10:48,130
Cool.
122

123
00:10:48,170 --> 00:10:55,070
So we're bringing up a blank table view because, currently, we still don't have any categories. And you
123

124
00:10:55,070 --> 00:10:58,680
can confirm that if you go into the SQLite database.
124

125
00:10:58,820 --> 00:11:08,600
But if we add some new categories, let's say, I don't know, Shopping List, maybe another one called Home,
125

126
00:11:08,660 --> 00:11:12,980
and one called Work, and maybe one called Miscellaneous.
126

127
00:11:13,490 --> 00:11:13,810
Okay.
127

128
00:11:13,850 --> 00:11:21,560
So we now have four categories. And we can check to make sure that they are indeed being persisted using
128

129
00:11:21,560 --> 00:11:28,910
Core Data by double tapping the home screen, terminating our app, and going back into our app.
129

130
00:11:28,910 --> 00:11:33,070
And as you can see, they are still exactly where we left them.
130

131
00:11:33,080 --> 00:11:35,960
So our code has succeeded.
131

132
00:11:35,960 --> 00:11:41,990
So if you had any problems setting up your code up to this point, then it might be worth going back to
132

133
00:11:41,990 --> 00:11:46,430
your code and seeing if there's any errors or bugs that you can fix.
133

134
00:11:46,490 --> 00:11:51,860
Now, in the next lesson, we're going to set up our Table View Delegate Methods, namely, what should happen
134

135
00:11:51,950 --> 00:11:58,280
when we click on one of the category cells, because when I click on home, I wanted to take me to a table
135

136
00:11:58,280 --> 00:12:04,670
view that contains all of the to-do list items that are associated with the home category.
136

137
00:12:04,730 --> 00:12:07,730
So for all of that and more, I'll see you on the next lesson.
