Hey guys going on this is Caleb with Dev's Loeb's dot com.
And in this video we're going to write a function that's going to save our data for our goal to core
data to our persistent store and we're going to dismiss bact goals.
VC K open your X code project and we're going to go ahead and do this.
Now open up finished goal visi.
And here is where the magic's going to happen.
Right here is create gold button was pressed.
This is what we're going to save all of our things that we've passed.
We've passed in a gold description from Kriegel VC we've passed in a gold type and we've also set a
number of points in our points textfield K. That's really cool.
Now there's one thing we forgot.
Actually we have a back button that we did not yet set up so tap on main story board open up the assistant
editor and make some room and right beneath create gold button was pressed.
Go ahead and drop an Iby action called back button was pressed and just like before.
Here's what we're going to do.
We're going to type dismiss detail and it's going to dismiss back to the previous view controller.
Just like a navigation controller.
OK.
So sorry.
Let's move on back to what we were going to talk about before I realized that we forgot the back button
and we're actually going to add a function called Save and this is going to utilize core data to pass
in an object into the managed object context and save it in our persistent store.
So go ahead and import core data to begin with.
And we're going to go ahead and write this function now so you know what.
Let me give you some more room here so you can see everything.
There we go.
All right.
So go ahead and type phunk save and that is going to be the name of our function but we need to know
when saving is complete when it's finished when it's not.
Because if it does finish successfully we want to dismiss the view controller if it doesn't we want
to at least print an error to the console for now.
So we're going to go ahead and build a completion handler which is basically a function that we can
pass a value to and whenever we call this function we can get that value wherever we call this function.
So go ahead and type completion and we're going to go ahead and inside of our bracket here we're going
to make a function.
OK.
And it's going to to first take a parameter called Finished of type bool and this function is going
to return an empty function cause we don't care what it returns at the end.
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.
OK.
So that's our completion handler.
And what we're going to do now is we're going to go ahead and set up the managed object context in the
what is core data video.
I told you that you would be interacting the most with the managed object context so we're going to
go ahead and create this now.
But before we do that we need to create an instance of our app delegate because when we create a project
with core data if you scroll down to the bottom you'll see that there is a lot of interesting things
in here from your core data stack.
We have a persistent container we have a function that lets us save the current context.
There's stuff for core data built right in.
And it does that for us which is incredibly helpful but we need to go to two goals Fisi and we're going
to create a constant that is accessible publicly across all of our controllers by writing it outside
of the class.
So go ahead and type let app delegate equals UI application shared application or shared delegate.
OK that gets our apt delegate but we're going to optionally cast it as type app delegate.
OK so there's are app delegate We now can access that from anywhere.
And we're going to use that now in our Save function in order to get our managed object context.
OK.
So go ahead and type guard let managed context.
And we're going to set that to be equal to the app delegate the one with the lowercase a persistent
container view context.
OK.
This is how we get our managed object context from the main queue it's the one that's associated with
the main queue it's our main managed object context OK.
Now if we can't get that for some reason we're going to just go ahead and call.
Else return.
Because if we can't get this we should not move forward.
Now what we're going to do is we're going to create an instance of goal an instance of goal meaning
our goal model our goal entity from core data.
So go back and tickle a finished goal VC and type let goal.
And remember we can just type goal as if it was a swift class super super cool.
And in order to this properly we need to tell the managed object context which model it's going to be
using in order to create the persistent storage coordinator.
So put a print next to it and you'll see we can pass in a context press enter and pass in the managed
context.
Supercool.
So now we have created an instance of goal and we've given it a managed context that it needs to know
so that it knows where it's saving the data so that it can be properly managed.
Very very cool.
Now believe it or not we can use this just like any other swift class we can call goal and now we can
set all four of these properties.
We've already passed in a goal description and initialize that when this view controller is created.
So go ahead and just type goal goal description and set that to be equal to goal description.
The one from this view controller.
Next go ahead and type goal dot goal type and we can also pass the goal type from this view controller.
Next we have goal dot goal completion value.
We can set that to be equal to the textfield right points textfield tells us how many we have.
So we can go ahead and type points textfield text and unwrap it right because it's coming from a textfield
which has an optional string but it's giving us an error cannot assign value of type String type into
32.
Remember that inside of our goal it's what we need to look at here.
We're saving goal completion value as an in 32.
So what we're going to actually need to do is cast this as an in 32.
So I'm going to put it in parentheses and at the beginning I'm going to go ahead and type and 32 and
that will cast it as an in 32 value.
So whatever is inside the text field we're saying this is a number and we know it can only be a number
because we have set the number pad.
Now in order to properly forecast this we need to unwrap it at the end so just do that.
But we know for sure that the number value which will be an integer we can cast as an in 32.
Now remember gold type in and of itself is what type.
Can't remember gold type.
OK.
So gold type has an inherent value of string but we need to pull out the raw value to actually access
that as you can tell the raw value of the raw type is string.
So in order to set the goal type we need to set the raw value because Chordata cannot accept gold type
as as a type.
OK.
So then what we're going to do is we're going to set goal goal progress like so.
Now if you saw gold progress is 32 as well.
When we create our goal we have made zero progress on that goal.
So we should call in 32 and we should give it a value of zero.
Okay we're going to set in 32 of 0 as our goal progress that's how we're initially starting out is at
zero.
Pretty cool.
So this is great.
And we have set this but we have not yet told the managed object context to pass this into persistent
storage.
We have simply set up a model.
So in order to do that we're going to go ahead and call managed context that's safe.
Now you'll notice it says throes.
Right.
And that is where we're actually going to need to use a do catch block K because we can say do meaning
do this try to save the Manage context and then we can call catch meaning if there's an error.
We're going to catch it.
And in order to print out the error we're going to use Debug print and debug print writes the textual
representation of the given items most suitable for debugging into the standard output.
It just helps us out.
So debug print and we're going to say could not save.
And we'll just print out the error that is thrown.
Like so.
Well of course this needs to be a string.
So the error that's thrown is here but we should definitely print out the localized description because
that will give us kind of a plain English version of the error.
So awesome.
This is great.
But in order to actually successfully try this we need to call try.
OK.
We're going to use do try to save our context if it doesn't work.
We're going to catch the error and we're going to print it here so that we know what's going on.
Now this is great and all but we need to be able to tell our completion handler when we're done.
So if saving happens properly we're going to go ahead and call completion and pass it.
True if it doesn't work properly it's going to print out and we're going to call completion false.
OK.
So that's pretty cool.
We're telling it we're good.
We're complete or we're saying we're not complete we didn't finish.
So this is how we're going to save to Chordata K supercool we're using our managed object text we're
creating a managed object model and we're using save in order to commit unsaved changes to the context
parents store right which if you look here is the persistent store coordinator.
Very very cool.
So now we need to think about where we're going to save this create Go button was pressed.
Let's do it.
So we're going to call self save and the completion block we're going to set as.
How about complete.
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
going to go ahead and dismiss.
And we're going to say true.
And the completion will be nil.
So we're not using our fancy dismissal we're just going to dismiss all the way to the main view controller.
Now there's one thing that I want you to think about here.
What if we have not yet typed anything in point textfield that's going to cause some problems.
So we need to verify that we have actually type something before we can even create this goal.
So go ahead and type if points textfield text is not equal to nil.
We're going to call self-direct save.
All right.
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
it did not work.
You know what how about this.
If it does work let's just print successfully.
Oops.
Fully saved data so we can just check to see if we're good to go.
And if it properly dismisses.
Build and run and our simulator will come up here.
Let's go ahead and yeah let's pop open that view controller eat salad twice.
That's a short term goal let's say that this will be done in two salads and create a goal OK successfully
save data and dismissed but look at this it's still showing our previous view controller that is not
at all what we want.
So we're going to need to fix that but let's do that in the next video.
Then after that we're going to go ahead and write our function to fetch all this data from our core
data data model.
Super duper cool.
Awesome job guys.
We will fix that dismissal in the next video.
Great job with this one.
Acia there.