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