What's up guys I'm Jacob Bledsoe at slopes Delcam and we left off getting our run model all all ironed
out and explained some stuff about Rome and what's required.
And now that we have that before we get started this pull up our terminal.
I'm just going to make sure I create a branch for this lesson right.
And that is done.
So when I create data models I like to manipulate everything with that model inside of the this class.
So like when I'm saving to the run object I want to call a function that is inside the run object that
will save everything for me.
And that way you're not you don't have your code all over the place.
Things are nicely contained and like you know if you want to save a run object you just can call the
run class and find exactly what you're looking for.
So when I create objects like we want to save our run object from our current run screen when we end
the run we want to save that object to relm right.
So why don't we make a function and you have to make it static because we only want one instance of
it we don't want it to be able to be overridden or anything like that.
So static func and we will say add run to realm and that is what we're doing.
This lesson is we are saving our run objects to relm OK.
And what do we need to create an object we need our pace which is type and we need our distance which
is a double and we need our duration which is another end.
All right.
And so when the user passes those in everything inside this function will take care of saving it to
relm OK.
But basically what static allows us to do here is we don't have to create a a static instance of the
run object like you we have done and other things we've made like data services and stuff like that.
We'll actually be able to just go to our current run location and if we go to end run we want to add
our relm code here right.
We can just call our run object or run Stut swift file and say add a run to Relm
and that's pretty cool.
One second I wanted to see it save.
So if we add at run to Rome and there we go we can passen the pace great.
We can pass in the distance which what do we we call it run distance run distance and then we can pass
in the counter which is the duration.
So then this is all that's required on our end run to create our relm object and that's really nice.
And so we know we want to create a run object so we call our run class and we can just add our realm
object just like that.
And that's why I like to make my my models this way.
We don't need a static instance of it we make the functions static and everything works from that point
on.
So when we're dealing with a realm you need to create a realm instance for every time you write.
And every time you read.
OK.
So one thing that you need to do is they're going to like the documentation.
Let's just look at this real quick.
When you do a write
says find it they always show just force on rapin with a try but we're not going to force on RAP we're
going to do just the do try with a catch just like you're supposed to do for air catching.
So if an error does happen it's not likely that a realm right air will happen but you want to write
code for it.
Otherwise you're just going to crash instead of recovering from it.
Right.
So we're going to put a do here and at the bottom of do you catch it and then we're going to do is just
do a Debug.
Print and this is just going to be a print statement when we're in debug mode.
So running on the simulator and stuff these actually won't ever get put in your app when you publish
it to the App Store.
That's why I like to use Debug print instead of just a print statement.
And I'm just going to type air air adding run to relm just so we know if we get an air we know where
it occurred.
Right.
So inside this Do statement we need to get a reference of the realm.
So we're going to do let relm equal and then we need to try.
And then we just create an instance of realm just like that and this calling realm like this set calls
the default configuration and all of that stuff so realm out of the box will work just fine for us for
now doing it this way.
And we will run into an issue later where we are going to have to do something a little different than
this.
But for now this is perfect.
And then once you do this you just do try relm with the instance you just made.
Right.
And then you need the opening and closing bracket and then you'd simply say relm dot add.
And then we pass in our object which we haven't created yet but we have everything we need to create
that object.
So why don't we go ahead and say let our run equal and then call this class run and we are looking for
our initialiser right here and we can just simply pass in our pace distance and duration which we passed
in from the other view controller.
So we took all these variables created the run object and now in round out add let's just pass in our
object we just created and get rid of the space hafter realm right.
So with that being done we just added our objects realm it is now being stored.
And then another nice thing to do is try relm don't commit.
Right.
And this kind of just makes sure it doesn't leave with anything open.
You don't need this but when I was I ran into some instances where it is good to confirm that you're
right is committed.
You don't need this but it's it doesn't hurt to have it.
It's a safe safe thing to make sure that the realm right is committed and done when you're finished.
And so right now we are good.
And if we we already are calling our function from our current run VC.
So when we end the run it would it would save one thing that is good because rights to relm are asynchronous.
So we're going to want to take it off the main thread and do like a dispatch.
Q Okay.
Like a cereal dispatch.
Q But we want to make sure we're always calling it on the same thread.
So if we go to our utilities folder let's create a new file and a swift files.
Good and let's call this Constance
and we're just going to create some constants here that we can use globally everywhere.
So this is going to be let and we'll call this realm underscore.
Q And we're are going to set this equal to a dispatch queue Q And then we can give it a key.
So it always uses the same dispatch queue and we'll call this our realm.
Q Nice and easy and see that I just made this a global variable so I kept everything all caps so it's
very obvious that's what it is.
And if we go to our run here all we do to call that would be Rome.
Q And now are our dispatch queue will queue up all of our asynchronous rights if that happens like we
called a bunch in a row.
They could stack up but at least we're taking them off our main thread.
And this is allowed because it's always going to the same thread now.
And so if we ran this let's just make sure our current run calls yes our current run is coin.
Add to around and we're passing it in.
So if we run this app let's just get I don't want the 7 plus it's too big takes too much time to get
it going.
Or so our apps loaded up were already on a run.
You see it working with say start run and duration starts counting pace starts calculating and distance
starts increasing.
So we have a run here right now.
If I end this run it should add our data to relm and we didn't get any crashes.
So that's a good sign that means it successfully added our object.
So why don't we just start around one more time.
So we have a couple pieces of data when we start reading it.
All right.
So let's just I don't remember what we took our time to last time or distance let's just make sure it's
different.
All right let's go ahead and end this run.
So now we have two runs to run objects saved to our realm database.
So that's really cool.
And we don't have any crashes.
So now we have to start getting them displaying in our table view log right.
So to do that let's go back to our run model and in our run model we're going to have to make a function
for retrieving our data.
OK.
So we're going to do the same thing we're going to make a static function.
So go ahead and type static func and we'll call this get all runs.
And this needs to return
a collection called results and what results are is pretty much like a dictionary were it's unordered.
So every time you would get all your runs you can't guarantee the order but you can like say you want
object 0 like index 0 like an array and pull that out but it's not always guaranteed to be the same
object.
So results are not ordered So when you do get your results you need to sort them and do all that cool
stuff but we'll get there in a second.
And we want a we want a collection of results with type run inside.
So our object run and this is going to be an optional because we're calling the realm database.
We don't even know if there is data there.
Right.
So it's an optional value and then opening and closing brackets is perfect.
And let me just do some spaces here so my code is more in the center for you guys.
And right when we are doing when we're retrieving our realm object we are going to do a do catch again.
So if it does fail when we create our instance to realm at least we're catching the error in our app
doesn't crash.
We might not have data but at least her app doesn't crash.
So do it do whoops do it do opening brackets closing brackets and then catch opening and closing brackets
and end the catch.
We're just going to return nil because it's an optional right.
So if nothing is there we'll just return nothing.
So if it errors out polling our run our run collection from the database will just return nil which
is fine.
So now we need to create an instance to Rome.
So we need to do let relm equal try realm just like above we need an instance to just our default realm
configuration and then we need to create a variable for the runs.
OK.
And so we can simply just do var runs equals relm dot objects of type runs so we want our object.
Our model run.
And it just needs to be self so we're calling it's we're calling our run object.
OK.
And so this is as much as you have to do to actually get a value we could just return this so we could
just do the return runs.
There we go and we could get data now.
Why don't we do that.
And then we'll get into making sure we sort it by the date and all that stuff.
So in our location in our begin run VC just in view did load.
Let's just do a simple print statement and it'll be like here are my runs colon and then backslash opening
and closing parentheses.
And let's just call our run swift file and get all runs and this should just print out two objects for
us down here in our console.
So let's go ahead and run this
and this is yelling at us because it's an optional and that wants a default value but that's fine for
now.
And look at that.
I'm going to just end this here and we have our two run objects with are automatically created you know
our our randomly generated IDs and then we have our N.S. date of when it was created.
And we also have our pace here in seconds our duration in seconds in our distance.
So this is really cool our distance in meters right.
So we have all of our data here.
But now if we run this again I just want to see the duration.
So the first one is 15 right now for duration.
Let's just run this again and see if 15 is still in the top it's not guaranteed.
But you also don't it could just happen again because we only have 2 objects and it is in the top but
it's just like dictionaries the order is not guaranteed but that's really cool that we have data there.
And you're seeing it.
So let's go back to our run here and a really cool thing.
In our Since we've made date an index property we can simply just do this for sorting we can say we
want our runs variable to equal runs.
So we're calling this data still and we're just going to say daat sorted and we want it by key path
and we just called date here is spelled the same exact way as our variable.
All right.
And then we want ascending to be false.
If we made ascending true it would be the very first run would come first.
But in this case we won our last run to come first right.
So we always want the newest date to be on top and that is as much as we have to do to sort our runs
in order.
So now if we run this again and this prince it's probably going to be in the same order I didn't really
pay attention to the time stamp but we'll see.
Oh I removed the print statement.
That's I'm just going to undo and.
All right.
Now let's run it again and we'll see our runs and nothing.
It might not be any different but it will show it'll always return that same order.
Now oh and there we go.
So the duration for 16 was actually sooner than this one.
And so now this order will always return this way because we're sorting it by the time stamp which is
really cool.
And it didn't take any effort to sort that.
So
right there is like one of the huge reasons for using realm aside from like off line data persistence
and all that cool stuff.
So that is how you would retrieve your runs which is nice and easy.
We will call this video done and in the next video we are going to be grabbing all of our runs data
and getting it in our collection view in our in our run log.
Let me just find our run log here.
So we'll load everything on the table view straight from our role model we won't store it anywhere else
we're just grabbing straight from Rome.
So that's really cool.
So before I get off.
Let's go ahead and do a get ad period a commit Dasch am and we did let's see ad and I should say right
and fetch methods for around for a run object for relm or for run model done.
OK.
So there we go and I will see you in the next lesson guys.