ECS189H_2009-11-16

UC Davis Academics
12 followers
1 Video View·Dec 1, 2023
Lecture 14: Core Data Recap (What is it again? How do we use it?)
Sorry I missed on Friday, I was a little busy at work last week.
So, yeah, the only announcements I have are that the projects are due in, is it less than two weeks?
Less than two weeks, so, no, is it?
I guess we have three weeks.
We have until December 4th, which is two to three weeks away.
So I'm anxious to see milestones this week on Friday, I'll definitely be here.
So, yeah, any questions from folks?
Concerns?
Are the projects you chose too big?
Too small?
You're already finished?
No?
Okay.
So today we're going to do a little bit of a core data recap.
So for me, I think when Colin presented it, I'd say for many of you that was probably the first time you saw core data.
For some of you, maybe not.
For me, that was also essentially the first time I sat down and had anyone actually tell me about it.
So what I've been trying to do is spend a little time to learn it as well.
So I'll present as much as I can today.
I only got to a certain point in terms of me learning it.
So hopefully some of what I've learned will actually help you.
And then probably what will end up happening is on Friday we'll finish up with it
and also include key value coding and key value observing,
which is something you may have seen in the documentation while poking around through various things.
And that stuff's interesting because it's sort of how, well,
some of the things that seem like magic with core data are because of key value observing and key value coding.
And it's also how some of the interface builder stuff happens behind the scenes.
So we'll look at that on Friday and maybe the accelerometer because we'll have, like,
the things we have are sort of smaller now, little chunks of things.
So okay.
So core data recap.
So what is it again?
Does anyone vaguely remember or have some thoughts as to what it is?
Some opinions?
Yes.
Isn't there a place where you can store your data that's in, like, a file system sort of?
Okay.
So yes, that is part of it.
So it's a, well, so you can think of it as a place where you can store stuff.
So that's like a piece of it.
So core data itself is this API that lets you manage your models in some way.
So we've talked about the model view controller pattern a number of times.
And we've seen that the views come from the interface builder world.
And then sort of the controllers and the models are things that we've been working on ourselves in code.
So core data and some of the tools that it provides gives us the M part of the model view controller pattern stuff that we've been using.
And it provides some tools that help us create these models in a nice visual way.
And then it basically, core data itself is a set of APIs and objects that basically allow us to save data in certain ways.
So we can either, the data we store doesn't necessarily have to be stored to a file.
It can actually be in memory, in which case it's, you know, unless your machine never turns off, I guess it's not really persistent.
But that is an option.
So let's see what I've got here.
And we'll sort of see how to use it as we go through.
So when talking about core data, basically, usually we refer to this core data stack.
And these are these objects that, well, that work together to read and write data to some sort of storage.
So that storage could be file storage, could be a database, could be memory.
In general, when people are working with it on the iPhone, it tends to be, like the store, tends to be an SQLite database.
But it doesn't have to be.
So I feel like I'm doing this backwards because I have some slides towards the end that talk about modeling.
But we'll go through it this way, and then we'll sort of back up again.
And hopefully we'll have a clear picture of what core data actually is.
I guess before I go in, I'll step back and just say, in general, the way to think about it is core data gives you some sort of abstraction.
to stuff that you want to store.
And generally what happens is through the APIs that they provide, when you reach into that store and pull things out,
you get them in a way that you're used to using them, which is through objects.
So you've created your own models already where you've got various properties on them.
So there's a person model, and the person has a name and a social security number and various other attributes.
So core data helps take care of storing that stuff in some way,
and then retrieving it efficiently to display, to interact with in some way.
So generally when talking about core data, we refer to, yes?
So for those of us who are familiar with object-relational mappers,
is core data really any more than just an object-relational mapper with some associated visual tools?
Right, so I'm also familiar with object-relational mapping.
So for those of you who've used Ruby on Rails, for example,
Ruby on Rails provides something called active record,
which is this abstraction, this ORM, abstraction over your database.
So what happens is if for whatever reason you want to use a MySQL database as the back end,
you can do that.
If you want to use Oracle's whatever, that doesn't really matter to you
when you're actually interacting with your database,
because what you end up getting are just these objects that you interact with.
And core data does provide that.
I haven't used it enough yet to really know whether it gives you much more than that.
But in general, the way to, and we'll look at it when I talk about modeling,
but the general way to think about what's going on with core data,
when you're creating these things called entities,
these entities tend to be tables, and these tables have cells,
or have columns, and these columns represent various properties.
And then the rows in these tables represent instances of objects from your store.
So in that regard, yes, it is.
But the thing that bugs me is that in none of the documentation that I've seen so far
has Apple actually referred to it as an ORM.
So it makes me feel like there's something more there.
And I think the something more that could be there
has to do with this idea of bindings.
And so key value coding, which we haven't discussed, and key value observing.
So I'll just mention them briefly right now,
just because I did want to talk about it today, but I didn't think I'd have time.
But I'll talk about it.
So key value coding basically is a mechanism
where you can access instance variables of your model classes via string.
So normally you have your model object, and you say,
hey, model object dot whatever my property is.
Instead, you could say whatever my object is, value for key,
and in a string, property name, whatever the property name is.
So that's the first piece.
So basically you can get inside of your objects by just poking them with some strings.
And the other part, so you can get inside your objects by sending in some strings.
And you can access these instance variables even if properties haven't been created.
So we've been setting up these app properties, retain stuff.
Even if you don't set those up, you'd still be able to access them.
The other piece of it, and again, I haven't used this stuff very much at all really.
But the other piece of key value coding is key value observing.
So what happens is you can set things up so that when data changes in some place,
you will be notified of that having happened in some other place.
So that could be useful if you have a lot of views,
and they're all sort of poking into one model.
And based on whatever happens, you want these various views to change.
So in a way to minimize the coupling between all of these objects,
well, key value observing facilitates this stuff.
So I would say that's how it's different from a traditional ORM
in that when you access or modify something,
there are some notifications and things that happen in the background.
That's my first guess at it.
So if you find something else about it, I'd love to know.
Okay, so usually when talking about core data, we refer to a core data stack.
So these are just the objects that work together to read and write data to some storage.
So this I pulled right out of Apple's documentation.
This is a representation of the core data stack.
So at the very bottom, we have this store file.
And then moving up, we have persistent object store,
so a collection of object data, persistent store coordinator,
a collection of stores.
And then off to the right, there's this managed object model,
which people like to call Mom.
And then at the very top, there's this managed object context.
So let's go through each of those and say something about them
and see what we can learn.
So the persistent object store manages storage.
So I mentioned earlier that the storage doesn't necessarily have to be a file,
but it could be.
So it would manage the opening and closing of these files
or setting up whatever it needs to set up,
allocating the memory that you might be utilizing.
The other thing that it does is it takes care of mapping between data in the store
and objects in the managed object context.
So we'll look at what the managed object context is in a little bit.
But basically, if we look here at the very bottom,
so things sort of, you know, they'll kind of move up and down this stack
as you interact with things.
And at the lowest level, you can imagine that the persistent object store
at some point has some sort of information that is your object's representation.
And in order to get your object and shove it into an SQLite database, for example,
or into some other sort of binary file,
this persistent object store, which is very specific to, say, SQLite,
will take your objects and transform them into some sort of data
that SQL can utilize, for example.
Yes?
So it's a collection of converters?
I would say the persistent store coordinator is more,
so would be more of a collection of them.
The persistent object store itself, as far as I understand it,
tends to be very specific to a particular type of storage, for example, SQLite.
And we'll see as we, I have another picture somewhere towards the end
that maybe makes that a little more clear.
So this persistent object store, there could be multiple persistent object stores,
and they would be all managed by the persistent store coordinator.
On the iPhone, generally, you will generally just have just one,
and it will tend to be an SQLite-backed object store.
So in terms of the persistent object store itself,
your interaction with it is fairly minimal, as far as I understand it,
besides just creating it.
You're pretty much kind of, you know, you've created it, you've set it up,
and there it is.
And as far as the iPhone is concerned,
you have the type of storage that you can have is SQLite,
so a SQLite database.
There's some sort of binary representation.
And then you can also, if you wanted to, you could use memory to do various things.
So utilizing the main memory for this is definitely doable.
It probably would be a situation where you have a number of objects,
but they don't take up a lot of space,
and just the interaction that core data gives you,
the ease with which you can bring data in and out and manipulate it,
it might make sense to do that.
Okay, so next up, the persistent store coordinator.
So that sits between these managed object contexts
and the persistent object store.
And basically, it's a generalized interface to the persistent object store.
So like the question that was asked a little bit ago,
basically, as you go lower in this stack towards the persistent object store,
things start to get more specific.
So as you move up to the persistent store coordinator,
it's much more of a generic interface between your model,
your managed objects, and the persistent stores.
And if we look off to the right of the persistent store coordinator,
it has information about the managed object model.
So the model is just the models that you're used to using,
these objects that have properties and whatever various bits about them.
And as far as, well, we'll look at the managed object model shortly,
but basically, the persistent store coordinator uses these descriptions
to facilitate the, I guess, the movement of information up and down this stack.
So the managed object model, like I just mentioned,
basically, the description of your model properties.
We have a person model, and the person has a name and birth date
and various other things that you can think of.
And next up, the managed object context.
So this one's at the very top of our stack there.
And the thing just says here, it's a collection of managed objects.
So what happens here, the way the documentation likes to refer to it is,
they say that it is an intelligent scratch pad.
So what happens is when you query this,
when you need objects from your persistent store,
basically, they'll come into the managed object context,
and they'll just be hanging out there.
And you can poke at them and do whatever you want to them.
And they're just hanging out there, and they're temporary.
And you can modify them in whatever ways you want to modify them.
And if you don't save them,
then your persistent store hasn't been modified in any way.
So in order to actually get that stuff saved off,
you have to actually tell them to go ahead and save.
So basically, all of this is just this abstraction,
these layers of abstraction that eventually gets you these model objects
that you can interact with.
And it seems kind of wacky at first,
but I think the more I'm looking at it, the more I'm like,
oh, this is pretty nice, and I'm looking forward to using it
for something in the near future.
So managed object context.
So another diagram I found in the documentation
that just sort of kind of a higher level,
well, another look at all of this.
So we have our managed object context up top,
and in this case, we have a few of them.
And they link up to some persistent store coordinator.
And in this case, we see the persistent store coordinator
has two persistent object stores.
So again, on the iPhone, you generally,
you probably will not have more than one.
But in this case, I think their image would have been more interesting
if instead of file, one of them would have been file,
and one of them would have been database or something.
Because what will end up happening is you can take all these things
from different persistent object stores
and sort of merge them all into a model that you will interact with.
So even though they're stored off separately,
you can actually sort of glob them all together and work with them.
So let's see.
I think actually, okay.
So let's take a look at how this core data stack is built.
And the way we'll do that is, well, we'll just look at the sample
like at the templates that Xcode creates for us.
And we'll walk through as much of that as I have sort of annotated.
And maybe we can try and figure out some other stuff too
for folks who have used it more in depth.
Yeah.
So basically, this particular project that I have,
I won't create another one,
but basically it's just a navigation-based application
and makes sure that, in this case,
you check that you want to use core data for storage
just so that it sets up a bunch of more things for you.
You can do it yourself.
It's just why when Xcode can do it for you.
Oops.
So if we take a look at our app delegate,
usually when things get set up, let's see here.
Try and get everything on screen.
Usually, I guess some things will get cut off.
What we're used to seeing is that we'll have this stuff
sort of put in there for us by the template.
Now we've got a few other things in here.
So managed object model mom, we briefly talked about that.
There's a managed object context,
and then there's some sort of persistent store coordinator.
So basically they've thrown in the things we need
to make our core data stack.
And if we look down below, we see a number of properties
to access those stack elements.
So let's see here.
So let's look at constructing this.
Okay, so in terms of actually constructing,
building the persistent store coordinator,
so this was that thing I mentioned
that we wouldn't interact with very often,
but you pretty much set it up, and then you're done.
So what's going on here?
Basically, we're getting a path to some file,
CoreDataMovie.sql, or CoreDataMove.
It was supposed to be movie when I wrote this.
So basically we're saying here's the path,
or here's the name, here's the path and name of the file
that we want to store stuff into.
And when you generate the template, you can look yourself,
but, well, I guess we can just jump there.
So the application's document directory,
it just does, you know, just some stuff
to help find the document directory.
And I think last time when we talked,
if you remember, when you want to save something,
when your application wants to save data,
you want to save that data to that documents directory
inside its little application bundle that gets set up.
And you want to do that because, well, first of all,
that's sort of one of the few places that you can write,
and it's the place where when the user does a sync
and does whatever backups they do with iTunes,
stuff from that documents directory will get pulled over.
So, all right, so this is the name of our file,
and it's going in some particular place.
And next up, we just say, okay, let's take our persistent store,
allocate it, and initialize it
with some sort of managed object model.
And we'll look at that one shortly.
But it's basically, you know, it's like,
hey, let's set up some pointers.
And remember, right, the managed object model
is this description of your entities
and sort of how your objects relate to each other.
So we initialize it, and that's pretty much it.
You probably want to do some of this stuff.
But for now, for us, that's good enough.
So let's take a look at,
should be the managed object model,
and let's see how that gets set up.
So, again, this, you know, the code's pretty short for this.
It's basically, okay, NSManagedObjectModel.
Well, so if it hasn't been created,
then go ahead and create it.
NSManagedObjectModel, and then MergedModelFromBundles.
So what this will do is it'll basically,
it'll look through all your application directories
and look for these moms
and basically glob them all together
and stick them into this one managed object model.
Yeah, I think during the compile,
I think that the models that you create
will be placed in this mom file,
but I'm not 100% certain,
but that should be what happens
because when it starts searching for these,
it's got to search for something,
and I think that's what it is.
So we've created the managed object model.
So, so far, we're basically, right,
we set up the persistent object store.
We've set up this managed object model.
So at some point, we're probably going to have to set up
this persistent store coordinator,
and let's see if that is next.
I'm sorry, that part came in for us.
Next up is the actual managed object context.
So in terms of the managed object context,
well, actually, we left out
the persistent store coordinator.
So at this point, we're going to go ahead
and create our persistent store coordinator
and our managed object context,
and we're going to assign the managed object context
the coordinator that we just created.
So the one thing I wanted to see that I'm missing
is the part where we actually tell it,
yeah, sorry, I went a little too fast
through the persistent store.
Wait, actually, no.
Okay, let me back up and start again.
So I was thinking we were at the persistent object store,
which we are, but it was also setting up
the persistent store coordinator at the very beginning.
So again, we find our file,
we set up our persistent store coordinator,
and we give it this managed object model,
which if we go in there,
it's some other setup that's happening.
The thing that is interesting,
or the next little useful bit
is the place where we actually tell it,
hey, here's how we're actually setting up
our persistent store.
So persistent store coordinator,
add persistent store with type NSQLite.
So this is where we're telling,
we're sort of saying this is,
here's the type of thing we've chosen to use.
So as usual, right, option, double-click on there,
and we should see some information.
So we'll see that if we wanted to,
we could use an NSBinaryStoreType or NSInMemoryType
if that was the right thing to do for your application.
So, all right, let's see.
I think that's all I wanted to look at in here.
So that stuff's all kind of generic old boilerplate stuff.
It's just important to know that in order to create this stack,
you know, you need your persistent object store
and the store coordinator and the managed object context.
And from there, let's see.
Well, so let's see.
Let's take a look at how we actually model the objects.
So we saw how to build up the stack
in terms of actually modeling.
So I mentioned this briefly at the beginning.
I'll mention it again.
So you'll see the words, you know,
you'll see the word entities thrown around.
In general, entities will correspond to some sort of a table.
And these tables, well, these tables have columns,
and those columns will represent properties of your objects.
And then the objects, you know,
the instances of your objects end up being rows in this table.
So imagine a table of person objects.
So a person has a name and a birth date.
And, you know, all of us are people,
and we're in this person's table.
So, you know, if we wanted to get data about me,
we could query this table,
and it would find the row with the name Sreban
and, you know, bundle that up into some sort of object
that you could now work with, and you could say,
oh, what's Sreban's birth date,
or what's his social security number, or whatever.
So that's sort of a very high-level way that, again,
I don't think it's necessarily the way that...
I don't remember if I saw Apple describe it this way,
so this is more of the object-relational mapping
sort of way of thinking about what's happening
in modeling your data.
But so, you know, in terms of actually doing the modeling,
when you select that, you know,
when you click that checkbox for core data,
you end up having some sort of model file in your resources,
and usually it'll have, like, one little thing in there,
but I've already gone and done some work in it,
so let me zoom in a bit,
and hopefully that's a little better.
So the idea is, in here, you know,
I was thinking of setting up something
where there's a theater model,
and theaters have movies associated with them,
so then there's some sort of movie model,
and that's what I was setting up here.
So I'll push these aside, and I'll just make some new ones,
and I won't save them,
just to see how I set up this particular thing.
So if you look over in the upper left corner,
you'll see, you know, you'll see your entity.
That's kind of your entity area.
So, you know, let's create a new one,
and we'll just call it Theater 2.
And once you set it up, you now, you know,
theaters have some sort of properties
associated with them,
so you can head over to this other section,
and, you know, add some sort of attribute.
So the attribute is your property.
So let's say that, well, we'll say the theater has a name.
We'll just do the same as what I did in the other ones.
And, you know, we'll set its type to be one of these things.
Let's say it's a string,
and then you can do some other things,
some other fancy things with the attribute.
You can set up some sort of regular expression on them,
a default value, minimum, maximum length.
This optional thing,
I don't have a good grasp of exactly what it is,
but the basic gist of what I've seen is that
generally you don't want these things to be optional,
and when they're not optional, it helps.
Maybe I shouldn't say too much about them
since I'm not 100% sure what the best way of using that is,
but the things that I have seen mention that
generally you want to unclick optional
because it somehow helps with the integrity of your objects.
So for now we'll just say non-optional
and look through the documentation at some point
to figure out what exactly that's all about.
So we've got a theater, and it's got a name,
and I don't know, what else do theaters have?
We'll say that they have today's date,
and there is like a date field that we could use in here.
But I'll just go ahead and use string, just to use string again.
So we've got our theater.
Let's make another movie model, or another movie entity.
So movie2, and again, our movie might have some sort of name,
same sort of stuff,
and maybe there's some sort of description for the movie,
and we'll just leave it at that for right now.
So what happens is we now have a theater model,
and we have a movie model, or we have these entities.
What we haven't really discussed or set up
is how these two things relate to each other.
So if you look closer, farther down here, we'll see.
We've got our attributes, so we've taken care of those,
and we have some sort of relationships.
So what we can do is we can say,
well, we know that theaters tend to play more than one movie,
so a theater has many movies in general.
And for the sake of this example,
we'll say that the theater is the theater at my house,
and so that basically my theater has many movies,
but my movies belong in only one theater, which is my house.
So what we can do, again, while on the theater model,
we can, instead of adding an attribute,
we can add a relationship.
And in this case, we'll call the relationship movies,
and again, we'll get rid of this optional thing.
And if we look, I'm not sure how legible
or how easy it is to see there,
but we have a few of these other,
well, there are a few other options.
So first off, there's destination.
So what this is, so this is basically where we're saying,
let's link up one entity to another.
So our theater two has many movie twos,
so we'll go ahead and set that up.
And if we zoom out, we'll see that it created this little arrow to it.
And as I mentioned earlier, a theater can have many movies,
so that is this idea of too many relationships.
So an object maps too many other objects.
So we can click that, and as soon as you do that,
you will notice that the arrow has now become this double arrow.
And one last thing that we want to do is take care of this delete rule.
So if this object is destroyed, how do we want to proceed?
And right now it just says nullify, which basically, well,
it won't do anything to any of its objects in the relationship.
So what we want to do, say we want to delete everything,
we want to do this cascade option.
And this cascade will, you know, if you delete the theater,
it will also remove movies.
So let's set things up in the other direction
because a movie has a theater associated with it.
And so let's select the movie and add a relationship for it.
And we'll call that one theater.
And its destination we'll say is this theater 2.
So now we have these double arrow things going around.
And some of the stuff I saw in the documentation,
they suggested that in general you want to make sure
that you have these inverse relationships set up.
And I think part of that has to do with just the efficiency
of doing various queries on these objects.
So the idea is if, well, in general I think
if you can map from one object to another,
you'd like to be able to map back the other way.
So in this case we can again say that, you know,
let's map back, in this case, to movies.
And once we do that, those two lines kind of, they become one.
And now we see, we can very clearly tell
when we look at the theater and we look at the relationship movies
and we follow the arrow, when we reach the end of it we see,
oh, there are two arrows there.
So this is clearly a one-to-many relationship.
If we go in the other direction, you know,
we eventually reach the arrowhead there
and there's only one of them.
So, you know, movies have only a two-one relationship,
a not-to-many.
So that's sort of the gist of how at least you set up your models.
So, you know, it's kind of, you know, it's nice,
like so far we haven't really, as far as these things are concerned,
we haven't written any code.
So the next step, and you don't necessarily have to do this,
but, you know, if you actually need to access the code for these models,
what you'll do is, so you can create a group.
You don't have to create a group, but generally you'll create a group
and say it's called models and you can easily do that, right,
create or click on there and add new group.
And, you know, select that and in this case, you know,
so say we grab, say we want to do a select all,
pretend that these other two aren't there,
and you actually want to generate the code for these models,
what you can do is, you know, go up to file, new file,
and when those things are selected, what you should see is an option,
you know, this new thing comes up for this managed object class.
And I think if things aren't properly, and let's check,
if things aren't selected, I'm not sure if that comes up.
So that could be, no, it does.
I saw something in the documentation about that thing not necessarily showing up.
So we've got, so we have our Cocoa Touch.
Let me check that again, I'm curious.
So grab these, new file, managed object class,
you go next, and you'll say, you know, where do you want to put these things,
and you can sort of, I didn't need to select them,
the fact that I selected them checked them off ahead of time for me.
So from here, what we can then say is finish,
and well, we can take a look down here at some things.
Generate accessors, generate Objective-C properties,
we want those checked off.
Generate validation methods, I haven't looked into,
but usually when you deal with models,
you want to do something that, you know,
to make sure that the data that you try to put into them is actually valid data.
So I suspect that this generate validation methods might be related to that.
I haven't looked into it, but that's my guess.
Because again, the model generally wants to try to protect itself and say,
oh, you're trying to give me bad data, no, you know,
I won't let you give me bad data.
So I'm going to cancel just because I've already generated those files,
and we'll look at them in a second.
And so the files it would end up creating, you know, will look very,
they'll look fairly familiar.
The main thing is we're now inheriting off this NSManaged object,
and, you know, so we've got some properties, right?
Our movie set up, we had a name for it, a description for it,
and then the movie is playing in some particular theater.
And if we look at the .m, there isn't very much that really,
the main thing that's different that we may not have seen is usually we say
synthesize name, and here we're saying at dynamic.
And all this is is basically a way to tell the compiler, hey,
if you're warning me about the fact that these setters
and getters don't actually exist, someone will supply them to you at run time.
And, of course, if you don't, then there will be problems,
but if you do, then things are good.
So if we take a look at the theater, same thing.
It's an NSManaged object.
It's got the things that we put in there.
So we said that the theater has a name, and maybe it tracks today's date.
And so a theater has movies associated with it,
and the way that that's sort of taken care of is movies are an NS set,
so this unordered thing with all of our movies in it.
And if we look down a little farther, we'll see another interface section,
and you might remember this from one of the earlier lectures
when we were sort of looking at Objective-C.
I think I spent a bit of time talking about categories.
So this is a way where, as a quick refresher,
you can take an interface like, say, theater, which was set up up here,
and in essence open it up and add additional methods to it.
So this is sort of the syntax for doing that,
and Core Data or this template took care of doing this,
generating these models from the entities,
took care of doing this stuff for us,
and basically add movies, remove movies, add.
They set up these methods for us.
Another way of injecting methods into classes is through protocols.
So protocols are a new, I think it's an Objective-C 2.0 feature.
So prior to that, the things that you're doing with protocols now
were generally done through these categories.
So we look at the implementation.
Again, not a whole lot going on.
So behind the scenes, Core Data will be taking care of stuff for us.
And again, dynamic, just telling the compiler,
hey, don't complain that I haven't created these setters and getters.
They'll be there at runtime.
Okay, so any questions up to now?
Yes?
When you first created these models,
were you then interested in getting sprites from other collection files?
Are you using them to copy things to your library?
So are you saying if you've now created these files,
you want to go and mess with them and add additional things to them?
Yes.
With the accessors that we had elsewhere, or?
Well, so that's where, so now you have all the accessors, right?
So the fact that when we saved these files out,
we clicked Generate the Objective-C Properties.
It put these things in place for us.
Again, the main bit of magic is that usually we would say
at synthesize the name of the property,
and that would actually, the compiler at that point
would generate a setter and a getter for us.
In this case, at dynamic is just saying that at runtime,
when you use this, there will be a setter and a getter there for you,
and that's sort of where Core Data will take care of that
if your stuff happens to be, well, in this case,
will be backed by some sort of Core Data store.
What I don't know is, and again, this is just because
I haven't played with this stuff enough yet,
is, well, now I have this theater object.
It feels scary because now what I can do is
I can go in and start making changes here to this file,
but if something happens and my model changes,
I feel like, and I've actually written things in here
and I haven't done them through, yeah,
if I haven't done it through here,
then you could end up clobbering over some of your stuff.
So that's something I haven't figured out yet
because I haven't used it enough, but in general,
I'd say as you're working with this, do everything,
set up your models through that modeling tool.
And let me make this go away, okay.
Yeah, okay, so we saw how to put some of these together
and connect them up.
Next up, let's take a look at our root view controller.
So we have these objects, but how do we actually
do anything with them?
How do we get at them?
And this is where there's an NSFetchedResults controller
that comes into play.
And this is something I haven't had a chance to look at
as closely as I would like to, but we'll go through it quickly
and then on Friday we'll finish up in more detail with it
and hopefully we'll have all our core data,
at least the initial questions that we have about it
sort of in place.
So at this point, this sample I don't think will run
because I've made some changes and didn't update things
in all the places that we need to,
but the idea with this sample, if you just build it
without any of the changes, what you'll see is a table comes up
and you can add and delete rows in that table
and it just keeps time stamps of when that happened.
So with that, to actually get at our data,
again, so we have this FetchedResults controller
and we'll start at some of the things that table view,
the methods that we need to handle,
and we'll see how this FetchedResults controller
sort of takes care of things for us.
And we'll first look at it, how it's used,
and then we'll see how it's set up.
So if we want to know how many rows,
how many sections are in our table view,
well, we just ask our FetchedResults controller,
we say, hey, get the sections and then give me the count.
So fairly straightforward for that.
The other thing we'll generally need,
so given a section, we'll say, well,
how many rows are in that section?
So again, we can grab, using our FetchedResults controller,
we can get the sections and then say,
give me some object at some index for that particular section.
So now we have some objects associated with that section
and then we can just say, OK, given that section information,
tell me how many objects are in there.
So now we know how many sections we have,
we know how many rows are in a particular section.
The other one that's usually very important
when dealing with table views
is this cell for row at index path.
So most of what you see here should be familiar
from having worked with it at this point,
but the first thing is we want to grab a cell
and we want to reuse one,
assuming that it was created ahead of time
or we've already created one.
If it hasn't, then we'll go ahead and allocate it
and set up whatever we need to set up for it.
So we've got our cell.
Next up now is we want to actually do something
with our little object,
so we'll ask the Fetched Results Controller
for some particular object at some place.
And this is easier than, I think, when we...
Well, it's fairly similar to how we did it in, say, the RSS Reader,
but now it's just the Fetched Results Controller.
You just feed it this index path.
You don't have to actually go in and grab anything out of it.
Basically, it's saying, you know,
go off to this table and grab me some object in that table.
So the example earlier, if we have this person entity
and we're querying, you know,
somehow the row with my name comes up,
you know, this managed object will be a person object
that has Shubhan's name and social security number in it.
And then from there, you know,
so we have our object.
We can say...
And this is where sort of that key value coding stuff comes in earlier.
So, you know, we can say,
give me a value for key name.
And I think the fact that we actually generated these files...
The fact that we've actually generated these files
and we have properties,
we wouldn't necessarily have to use that value for key stuff.
But, again, just to see sort of how it's done.
So we'll grab the name and the description
and we'll put that into this,
into the theater's table of movies.
Okay, so that's sort of, you know,
here's this Fetched Results Controller,
this thing that helps us get stuff.
Let's see how it's actually set up.
Okay, so this one...
Again, I think very briefly I'll just say
some of the things that the Fetched Results Controller
has associated with it.
And then next time, we'll start with the Fetched Results Controller
and look in greater detail
into sort of this connection of, well, we now have our models.
We have this Fetched Results Controller.
We'll look more deeply at, okay, here's how we actually...
Here's what it means to do all the things we do with it
and here's how to use it.
But in general, from the stuff I remember,
the Fetched Results Controller has a Fetch Request
associated with it.
And...
Let's see.
So then there's, you know, this Entity Description.
So, you know, our entities are Theater and Movie.
In this case, you know, we just had Event sitting here,
but from the default thing that Xcode generated.
But we would basically, you know,
this is where we could say NSEntityDescription
entity for name, and we could say Theater,
and it would give us, you know, or we'd say Movie,
and it would give us a Movie object
or at least a description for it.
Okay, so Fetch Request, I guess we can, you know,
we can choose how large, you know,
how many things we want to fetch at a time
just because, you know, you might have thousands of objects,
you don't actually want to grab them all.
With these, you know, when you do a fetch,
so actually, has everyone in here taken
some sort of database course?
I managed not to take one at UC Davis,
so I'm just, I'm curious.
I didn't get to play with mumps or whatever it was
that people use in that class.
But, you know, so you're doing some sort of query
on your database, and you're getting, you know,
you get back, you know, your rows of information,
in this case for us, we'll get objects
which represent those rows.
The sort descriptor basically is a way of saying,
hey, here's, you know, sort based on some particular key
or some particular attribute, and, you know,
in this case, do we want these things
to be ascending or descending?
And the sort descriptor, I'm not quite sure.
There's another one which is the,
there's a predicate which I'm not seeing in here,
but you can get, you know, the queries you make
can be fairly, well, as complicated
as you need them to be, or as intricate
as you need them to be.
So there is something, there's an NS predicate
which basically you can feed it,
see these little regular expression type things
to help pull your data in.
So I think, yeah, I think I'll just leave it
at that for today.
And on Friday, we'll look more deeply
into the fetch result controller,
and maybe we'll try and finish this little example
which will be like, here's some movie theater,
and here's some movies associated with it,
and let's actually do something.
And there'll be another sort of recap
of key value coding and key value observing
because that's very intimately connected to core data.
And I think, you know, we'll look at the accelerometer
and we probably won't spend too much time on it
because I don't know how many people are using it
for stuff, but we'll take a, we'll walk through
some of the examples and see how to filter
the accelerometer data using some low-pass filters
and things, so.
All right.
Is this, is core data slightly clearer for people
now, a little bit?
So-so, okay.
On Friday, it will be very, very clear, I think.
How many people are using it for their final projects?
Okay.
More people should use it.
Because it's actually, yeah, it's, yeah,
it seems kind of weird at first, but I think,
like, even as I'm, as I'm learning it,
I'm like, oh, okay.
It's wacky, but I think
once you get past a few of the, the,
kind of the setup things, it's actually,
it's very useful, so.
Okay.
See you next time.
Okay.
