1
00:00:08,130 --> 00:00:11,280
Hey guys going on this is Caleb with Devon Lopes dotcom.

2
00:00:11,310 --> 00:00:16,920
And in this video we're going to write a function that's going to save our data for our goal to core

3
00:00:16,920 --> 00:00:21,670
data to our persistent store and we're going to dismiss bact goals.

4
00:00:21,680 --> 00:00:27,060
VC K open your X code project and we're going to go ahead and do this.

5
00:00:27,060 --> 00:00:28,350
Now open up.

6
00:00:28,350 --> 00:00:30,200
Finish goal VC.

7
00:00:30,270 --> 00:00:33,640
And here is where the magic's going to happen.

8
00:00:33,660 --> 00:00:36,480
Right here is create gold button was pressed.

9
00:00:36,480 --> 00:00:40,200
This is where we're going to save all of our things that we've passed.

10
00:00:40,200 --> 00:00:47,820
We've passed in a gold description from Kriegel VC we've passed in a gold type and we've also set a

11
00:00:47,970 --> 00:00:50,810
number of points in our points textfield.

12
00:00:50,880 --> 00:00:52,260
That's really cool.

13
00:00:52,260 --> 00:00:53,790
Now there's one thing we forgot.

14
00:00:53,790 --> 00:01:00,390
Actually we have a back button that we did not yet set up so tap on main story board open up the assistant

15
00:01:00,510 --> 00:01:09,390
editor and make some room and right beneath create Go button was pressed go ahead and drop an IAB action

16
00:01:09,690 --> 00:01:16,170
called back button was pressed and just like before.

17
00:01:16,470 --> 00:01:17,980
Here's what we're going to do.

18
00:01:18,000 --> 00:01:23,840
We're going to type dismiss detail OK and it's going to dismiss back to the previous view controller

19
00:01:23,850 --> 00:01:26,450
just like a UI navigation controller.

20
00:01:26,780 --> 00:01:28,010
OK so sorry.

21
00:01:28,020 --> 00:01:32,300
Let's move on back to what we were going to talk about before I realized that we forgot the back button

22
00:01:32,820 --> 00:01:38,490
and we're actually going to add a function called Save and this is going to utilize core data to pass

23
00:01:38,490 --> 00:01:44,130
in an object into the managed object context and save it in our persistent store.

24
00:01:44,130 --> 00:01:47,750
So go ahead and import core data to begin with.

25
00:01:47,880 --> 00:01:51,580
And we're going to go ahead and write this function now so you know what.

26
00:01:51,630 --> 00:01:55,000
Let me give you some more room here so you can see everything.

27
00:01:55,020 --> 00:01:55,830
There we go.

28
00:01:56,100 --> 00:01:56,420
All right.

29
00:01:56,430 --> 00:02:02,910
So go ahead and type phunk save and that is going to be the name of our function but we need to know

30
00:02:02,910 --> 00:02:05,810
when saving is complete when it's finished when it's not.

31
00:02:05,820 --> 00:02:11,460
Because if it does finish successfully we want to dismiss the view controller if it doesn't we want

32
00:02:11,460 --> 00:02:14,360
to at least print an error to the console for now.

33
00:02:14,460 --> 00:02:18,600
So we're going to go ahead and build a completion handler which is basically a function that we can

34
00:02:18,600 --> 00:02:24,160
pass a value to and whenever we call this function we can get that value wherever we call this function.

35
00:02:24,150 --> 00:02:30,630
So go ahead and type completion and we're going to go ahead and inside of our bracket here we're going

36
00:02:30,630 --> 00:02:31,700
to make a function.

37
00:02:31,800 --> 00:02:32,330
OK.

38
00:02:32,550 --> 00:02:40,320
And it's going to to first take a parameter called Finished of type bool and this function is going

39
00:02:40,320 --> 00:02:44,500
to return an empty function can because we don't care what it returns at the end.

40
00:02:44,610 --> 00:02:49,980
We just need to be able to pass a value here and at the end it's going to return this value to us.

41
00:02:50,070 --> 00:02:50,700
OK.

42
00:02:50,940 --> 00:02:52,720
So that's our completion handler.

43
00:02:52,740 --> 00:02:58,140
And what we're going to do now is we're going to go ahead and set up the managed object context in the

44
00:02:58,170 --> 00:02:59,800
what is core data video.

45
00:02:59,940 --> 00:03:04,770
I told you that you would be interacting the most with the managed object context so we're going to

46
00:03:04,770 --> 00:03:06,320
go ahead and create this now.

47
00:03:06,540 --> 00:03:11,610
But before we do that we need to create an instance of our app delegate because when we create a project

48
00:03:11,640 --> 00:03:17,730
with core data if you scroll down to the bottom you'll see that there is a lot of interesting things

49
00:03:17,730 --> 00:03:19,830
in here from your core data stack.

50
00:03:19,890 --> 00:03:26,820
We have a persistent container we have an a function that lets us save the current context.

51
00:03:27,030 --> 00:03:29,630
Their stuff for core data.

52
00:03:29,630 --> 00:03:35,640
Built right in and it does that for us which is incredibly helpful but we need to go to a to goals VC

53
00:03:36,240 --> 00:03:41,690
and we're going to create a constant that is accessible publicly across all of our value controllers

54
00:03:41,700 --> 00:03:44,070
by writing it outside of the class.

55
00:03:44,160 --> 00:03:54,030
So go ahead and type let app delegate equals UI application shared application or shared delegate that

56
00:03:54,030 --> 00:03:55,180
gets our app delegate.

57
00:03:55,200 --> 00:03:58,420
But we're going to optionally cast it as type app delegate.

58
00:03:58,590 --> 00:03:59,280
OK.

59
00:03:59,520 --> 00:04:00,750
So there's our app delegate.

60
00:04:00,750 --> 00:04:06,990
We now can access that from anywhere and we're going to use that now in our Save function in order to

61
00:04:06,990 --> 00:04:10,170
get our manage object context OK.

62
00:04:10,320 --> 00:04:19,550
So go ahead and type guard let managed context and we're going to set that to be equal to the app delegate.

63
00:04:19,560 --> 00:04:25,470
The one with the lower case a persistent container view context.

64
00:04:25,530 --> 00:04:26,150
OK.

65
00:04:26,340 --> 00:04:31,800
This is how we get our managed object context from the main queue.

66
00:04:31,800 --> 00:04:33,720
It's the one that's associated with the main queue.

67
00:04:33,720 --> 00:04:35,870
It's our main managed object context.

68
00:04:35,870 --> 00:04:36,470
OK.

69
00:04:36,780 --> 00:04:39,960
Now if we can't get that for some reason we're going to just go ahead and call.

70
00:04:39,960 --> 00:04:45,420
Else return because if we can't get this we should not move forward.

71
00:04:45,510 --> 00:04:50,750
Now what we're going to do is we're going to create an instance of goal OK an instance of goal meaning

72
00:04:50,790 --> 00:04:54,780
our goal model our goal entity from core data.

73
00:04:55,060 --> 00:04:59,260
So go back and tickle a finished goal VC and type let goal.

74
00:04:59,700 --> 00:05:05,730
And remember we can just type goal as if it was a swift class super super cool.

75
00:05:05,730 --> 00:05:11,570
And in order to achieve this properly we need to tell the managed object context which model it's going

76
00:05:11,570 --> 00:05:15,320
to be using in order to create the persistent storage coordinator.

77
00:05:15,320 --> 00:05:22,220
So put a print next to it and you'll see we can pass in a context press enter and pass in the managed

78
00:05:22,220 --> 00:05:23,100
context.

79
00:05:23,180 --> 00:05:24,560
Supercool.

80
00:05:24,560 --> 00:05:30,980
So now we have created an instance of goal and we've given it a managed context that it needs to know

81
00:05:31,160 --> 00:05:37,190
so that it knows where it's saving the data so that it can be properly managed very very cool.

82
00:05:37,190 --> 00:05:42,980
Now believe it or not we can use this just like any other swift class we can call goal and now we can

83
00:05:42,980 --> 00:05:45,890
set all four of these properties.

84
00:05:46,070 --> 00:05:51,500
We've already passed in a goal description and initialize that when this view controller is created.

85
00:05:51,500 --> 00:05:52,490
So go ahead and just type.

86
00:05:52,490 --> 00:05:57,530
GOAL GOAL description and set that to be equal to goal description.

87
00:05:57,590 --> 00:05:59,210
The one from this view controller.

88
00:05:59,540 --> 00:06:06,590
Next go ahead and type goal Dago's type and we can also pass the goal type from this view controller.

89
00:06:06,590 --> 00:06:12,560
Next we have goal dot goal completion value.

90
00:06:12,560 --> 00:06:14,950
We can set that to be equal to the textfield right.

91
00:06:14,990 --> 00:06:17,540
Points textfield tells us how many we have.

92
00:06:17,540 --> 00:06:22,960
So we can go ahead and type points textfield dot text and unwrap it right because it's coming from a

93
00:06:23,240 --> 00:06:30,050
textfield which has an optional string but it's giving us an error cannot assign value of type string

94
00:06:30,310 --> 00:06:32,370
to type in 32.

95
00:06:32,390 --> 00:06:36,410
Remember that inside of our goal it's what we need to look at.

96
00:06:36,410 --> 00:06:40,830
Here we're saving goal completion value as an in 32.

97
00:06:40,850 --> 00:06:45,270
So what we're going to actually need to do is cast this as an in 32.

98
00:06:45,410 --> 00:06:51,470
So I'm going to put it in parentheses and at the beginning I'm going to go ahead and type int 32 and

99
00:06:51,470 --> 00:06:54,630
that will cast it as an in 32 value.

100
00:06:54,740 --> 00:07:00,410
So whatever is inside the text field we're saying this is a number and we know it can only be a number

101
00:07:00,410 --> 00:07:02,240
because we have set the number pad.

102
00:07:02,240 --> 00:07:06,540
Now in order to properly forecast this we need to unwrap it at the end so just do that.

103
00:07:06,710 --> 00:07:13,630
But we know for sure that the number value which will be an integer we can cast as an in 32.

104
00:07:13,660 --> 00:07:19,480
Now remember gold type in and of itself is what type.

105
00:07:19,490 --> 00:07:21,030
Can't remember gold type.

106
00:07:21,050 --> 00:07:21,490
OK.

107
00:07:21,740 --> 00:07:28,640
So gold type has an inherent value of string but we need to pull out the raw value to actually access

108
00:07:28,640 --> 00:07:32,510
that as you can tell the raw value of the raw type is string.

109
00:07:32,510 --> 00:07:38,540
So in order to set the goal type we need to set the raw value because Chordata cannot accept gold type

110
00:07:38,590 --> 00:07:40,030
as a as a type.

111
00:07:40,340 --> 00:07:40,930
OK.

112
00:07:41,120 --> 00:07:48,200
So then what we're going to do is we're going to set goal goal progress like so.

113
00:07:48,410 --> 00:07:52,020
Now if you saw go progress is an 32 as well.

114
00:07:52,070 --> 00:07:55,670
When we create our goal we have made zero progress on that goal.

115
00:07:55,670 --> 00:08:01,020
So we should call in 32 and we should give it a value of zero.

116
00:08:01,280 --> 00:08:08,120
OK we're going to set in 32 of 0 as our go progress that's how we're initially starting out is at zero.

117
00:08:08,120 --> 00:08:09,380
Pretty cool.

118
00:08:09,380 --> 00:08:10,720
So this is great.

119
00:08:10,730 --> 00:08:16,730
And we have set this but we have not yet told the managed object context to pass this into persistent

120
00:08:16,730 --> 00:08:18,780
storage we have simply set up a model.

121
00:08:18,950 --> 00:08:25,300
So in order to do that we're going to go ahead and call managed context that's safe.

122
00:08:25,310 --> 00:08:27,500
Now you'll notice it says throws.

123
00:08:27,590 --> 00:08:28,510
Right.

124
00:08:28,670 --> 00:08:35,450
And that is where we're actually going to need to use a do catch block K because we can say do meaning

125
00:08:35,540 --> 00:08:43,310
do this try to save the Manage context and then we can call catch meaning if there's an error.

126
00:08:43,310 --> 00:08:44,600
We're going to catch it.

127
00:08:44,870 --> 00:08:50,150
And in order to to print out the error we're going to use Debug print K and debug.

128
00:08:50,150 --> 00:08:55,700
Print writes the textual representation of the given items most suitable for debugging into the standard

129
00:08:55,700 --> 00:08:56,030
output.

130
00:08:56,030 --> 00:08:57,170
It just helps us out.

131
00:08:57,320 --> 00:09:01,930
So debug print and we're going to say could not save.

132
00:09:02,240 --> 00:09:06,140
And we'll just print out the error that is thrown like so.

133
00:09:06,420 --> 00:09:08,700
Well of course this needs to be a string.

134
00:09:09,080 --> 00:09:13,550
So the error that's thrown is here but we should definitely print out the localized description because

135
00:09:13,550 --> 00:09:17,900
that will give us kind of a plain English version of the error.

136
00:09:17,900 --> 00:09:19,360
So awesome.

137
00:09:19,370 --> 00:09:20,280
This is great.

138
00:09:20,300 --> 00:09:25,850
But in order to actually successfully try this we need to call try OK.

139
00:09:25,970 --> 00:09:32,420
We're going to use do try to save our context if it doesn't work we're going to catch the error and

140
00:09:32,420 --> 00:09:35,250
we're going to print it here so that we know what's going on.

141
00:09:35,480 --> 00:09:40,560
Now this is great and all but we need to be able to tell our completion handler when we're done.

142
00:09:40,580 --> 00:09:46,730
So if saving happens properly we're going to go ahead and call completion and pass it.

143
00:09:46,730 --> 00:09:53,330
True if it doesn't work properly it's going to print out and we're going to call completion false.

144
00:09:53,490 --> 00:09:54,070
OK.

145
00:09:54,470 --> 00:09:55,670
So that's pretty cool.

146
00:09:55,670 --> 00:09:57,070
We're telling it we're good.

147
00:09:57,080 --> 00:10:00,760
We're complete or we're saying we're not complete we didn't finish.

148
00:10:00,980 --> 00:10:04,300
So this is how we're going to save to core data.

149
00:10:04,370 --> 00:10:10,700
K supercool we're using our managed object we're creating a managed object model and we're using it

150
00:10:11,120 --> 00:10:15,140
save in order to commit unsaved changes to the context.

151
00:10:15,140 --> 00:10:16,730
Parents store.

152
00:10:16,730 --> 00:10:20,870
Right which if you look here is the persistent store coordinator.

153
00:10:20,930 --> 00:10:22,370
Very very cool.

154
00:10:22,400 --> 00:10:28,770
So now we need to think about where we're going to save this create Go button was pressed.

155
00:10:28,790 --> 00:10:29,560
Let's do it.

156
00:10:29,690 --> 00:10:36,710
So we're going to call self save and the completion block we're going to set as.

157
00:10:36,710 --> 00:10:38,290
How about complete.

158
00:10:38,900 --> 00:10:42,170
So we can save all of our data is here.

159
00:10:42,350 --> 00:10:49,820
We're going to say if it's complete ok if it's finished we're going to go ahead and dismiss.

160
00:10:50,840 --> 00:10:52,470
And we're going to say true.

161
00:10:52,640 --> 00:10:54,150
And the completion will be nil.

162
00:10:54,170 --> 00:11:00,340
So we're not using our fancy dismissal we're just going to dismiss all the way to the main view controller.

163
00:11:00,350 --> 00:11:02,790
Now there's one thing that I want you to think about here.

164
00:11:02,930 --> 00:11:08,110
What if we have not yet typed anything in points textfield that's going to cause some problems.

165
00:11:08,180 --> 00:11:12,720
So we need to verify that we have actually type something before we can even create this goal.

166
00:11:12,740 --> 00:11:18,260
So go ahead and type if points textfield dot text is not equal to nil.

167
00:11:18,260 --> 00:11:20,470
We're going to call self-deceit safe.

168
00:11:20,480 --> 00:11:21,300
All right.

169
00:11:21,620 --> 00:11:27,340
So pass that in there and let's go see if this works let's try it and if we get an error we'll know

170
00:11:27,380 --> 00:11:29,690
it did not work.

171
00:11:29,690 --> 00:11:30,500
You know what how about this.

172
00:11:30,500 --> 00:11:34,800
If it does work let's just print successfully.

173
00:11:35,100 --> 00:11:36,320
Oops.

174
00:11:36,440 --> 00:11:42,970
Fully saved data so we can just check to see if we're good to go.

175
00:11:43,250 --> 00:11:48,630
And if it properly dismisses a build and run and our simulator will come up here.

176
00:11:48,950 --> 00:11:56,280
Let's go ahead and yeah let's pop open that view controller eat salad twice.

177
00:11:56,420 --> 00:12:04,550
That's a short term goal let's say that this will be done in two salads and create a goal OK successfully

178
00:12:04,550 --> 00:12:10,850
save data and it dismissed but look at this it's still showing our previous view controller that is

179
00:12:10,850 --> 00:12:12,670
not at all what we want.

180
00:12:12,830 --> 00:12:16,970
So we're going to need to fix that but let's do that in the next video.

181
00:12:16,970 --> 00:12:21,920
Then after that we're going to go ahead and write our function to fetch all this data from our core

182
00:12:21,920 --> 00:12:23,340
data data model.

183
00:12:23,390 --> 00:12:24,270
Super duper cool.

184
00:12:24,290 --> 00:12:25,130
Awesome job guys.

185
00:12:25,130 --> 00:12:27,770
We will fix that dismissal in the next video.

186
00:12:27,800 --> 00:12:28,990
Great job with this one.

187
00:12:29,030 --> 00:12:29,570
Acia there.

