Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2009-421
$eventId
ID of event: wwdc2009
$eventContentId
ID of session without event part: 421
$eventShortId
Shortened ID of event: wwdc09
$year
Year of session: 2009
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2009] [Session 421] Introductio...

WWDC09 • Session 421

Introduction to Core Data on iPhone

iPhone • 1:00:50

Core Data is a powerful, efficient framework for data management and persistence on Mac OS X and iPhone. Learn how Core Data uses entity relational mapping, makes data storage and retrieval more efficient, and even helps you to display your data more easily. Explore the key components of the Core Data architecture and discover how Core Data can accelerate your iPhone application development.

Speaker: Miguel Sanchez

Unlisted on Apple Developer site

Downloads from Apple

SD Video (155 MB)

Transcript

This transcript has potential transcription errors. We are working on an improved version.

My name is Miguel Sanchez. I'm an engineer on the Core Data team. I just want to tell you, this morning when I walked out of the house my 4 year old son saw me all dressed up for the presentation he said, dad is today the day when you get to talk to your people? [laughter] So my people, I'm here to talk to you about Core Data.

[applause and laughter] So as you saw in the trans keynote yesterday, Core Data is an abstraction layer for the management and persistence of your data. It's making its first appearance in iPhone OS 3.0. But the technology itself has been around on the desktop since 10.4 so we're actually on our 3rd release of the Core Data technology So let me start off by telling you what is the problem set that we're trying to help you with. So you have a typical Core Data application, I'm sorry, a typical iPhone application that is displaying your data.

The data happens to be -- it has a need of being persistent on the file, on the device. As a developer you don't want to care about that so much. You want to focus on your data as the objects in memory that you're interacting with. You also have probably already learned that in the iPhone land you have to put a lot of effort in polishing the UI you have so that you can win those Apple design awards that we're going to give out next hour. But invariably you have to think about the backhand side of your application.

What's going on there? How are you going to get from your file into objects? How are you going to maintain your object graph in memory? And most importantly, especially on the iPhone, how are you going to do this very efficiently, both speed wise and memory wise? So this is the problem area where Core Data lends you a hand. This is an introductory session to Core Data.

The audience is expected to not have a lot of experience with Core Data so if that's you you're in the right spot. I'm going to be walking you through how to model your data, working with objects, and displaying results. We have a follow up session in the Core Data session track tomorrow morning at 10:30.

This is more of the intermediate to advance Core Data session where we tell you what's new between version 2 and version 3 of the technology on the desktop and on the phone. So if you have experience with Core Data that's probably where you want to go to tomorrow.

So let's start out with a quick overview of the framework. So the whole point of you using Core Data is for us to allow you to think in terms of objects and avoid all the database grunt work. So please let us do all of the efficient fetching and saving for you. Let us keep track of all your changes, maintain an undo stack, validate your objects, help you with relationship maintenance and let us do all of this efficiently.

So this is what we're trying to do for you. Now how do we achieve this? What's the contract that we need to sign with you? We need a model. We need a description of your data. So ultimately we want to present your data to you as objects. You don't have to worry about how it gets to the file or how it got to the file. You want to see them as objects. But we want you to describe to us what those objects look like and that is the model description of your data.

So as long as you give us a model, we're able to manage the data for you. We both create the store file and manage that file for you. Now some of you probably have experience with similar relational to object mapping technologies so I'm just going to introduce our vocabulary so that you can map it to this world if you have prior experience with this technology. In Core Data land, the data file itself is referred to as the store so if you hear me say store, that's the data file.

The data scheme or the data description, I'm going to be referring to that as the model, the actual objects that you're interacting with at run time, Objective-C objects, for us those are called managed objects. Those are just data objects. And the managed objects exist as part of an object graph which we call the ManagedObjectContext. So these are the high level terms that you'll see me throwing around, stores, models, ManagedObjects.

Let's go one step deeper, I'm going to walk you through a workflow of how you actually interact with the framework so that you can see that it's not very difficult to get it up and running. So the first step is to give us a model. So you're going to use Xcode to create the model file but then at run time we load the model or actually you load the model and then you give it to us. The first Core Data class you give that model to is an instance of something called the NSPersistantStoreCoordinator.

This is one of the central classes in Core Data. So if you tell the coordinator, you know I'm going to start working with Core Data. Here's the model. The second thing the coordinator needs to know is, this is the URL to the file that I want you to open with this model. So those are the two things that the coordinator needs and we set up the database connection for you.

And then you kind of forget about this because as I said you don't really want to think in terms of what's going on behind the scenes with the file. You're focus should be at the Managed Object Context Level. So you want to interact with your graph of objects. So the next thing you do is create an instance of a ManagedObjectContext class and associate it with the coordinator and that's it.

At this point you have what we call the Core Data Stack. It's all up and running. It's ready for you to start using. You're going to be creating your objects, inserting them into the context, probably you'll also be fetching objects from the database indicating the query that you want in an instance of an NSFetchRequest, another Core Data class, and we're going to be pulling in data from your rows into managed objects. So this is a typical workflow, what it means to work with Core Data. If you're more familiar, if you're more comfortable thinking in terms of database terms, the store coordinator is the part of Core Data that is going to be managing your database connection.

As I said before, the model represents your data base keynote. The managed objects are nothing more than the row of data, right? All of your rows in the database are going to be represented as separate instances of managed objects. And the FetchRequest is, if you're familiar with CPOL, this is where you're indicating the select from where, order by parts of your query. You're not necessarily using that syntax but conceptually that's what's going on there. So once again, it's very easy to get started with Core Data. You need to follow just four quick steps to bring up the stack.

Let's review, one, you need to load the model. Two, you create a coordinator and you set the model on coordinator, you say I'm going to be managing data of this kind. Then you point the store, I'm sorry, you add a store to the coordinator and the last step is you create a context which is going to be your main point of interaction and you associate it with the coordinator and then that's it.

At this point you're interacting with your objects and the context. So let me show you how easy this is by walking you through a demo. This demo is going to do nothing fancy. I'm going to simply do something that all of you can do with your bits out there.

I'm simply going to create a new project in Xcode and show you that we now have this little checkbox here for certain types of iPhone applications. So here I'm going to create a navigation based application and I'm just going to say that we want to use Core Data for storage, alright? That's how you include it in your sources.

So I'm going to call this demo 1. So I'm just going to walk you through the files that are created in this Xcode template so that you know where to look for the Core Data parts of the application. But first let me launch the application so that you know what you get from simply creating the project. So this is an Xcode template project so it doesn't do much but it does enough to show Core Data.

We display a UI table view and we have this little flash button that allows you to add records and the records are very simplistic in this case. They're just time stamps of events representing the time when you clicked on this plus button, right? And then we have basic delete logic. A lot of these has nothing to do with Core Data. This is simple UI kit code. So this is what the project does.

Now I just quit the app. It's Core Data so it has to be persisted on a file. If I launch the app again, its Core Data so it's bringing the data back up, right. So this is, again it's a very simple template but it's already using Core Data.

So what do we give you? Let's start by showing you where the stack is created. I said it was very easy so let me collapse the methods here. So here we have, remember I said the first step is to load a model, so there we have an accessor method where we message the merge model from bundle method or ManagedObjectModel.

There's other methods to load the model based on a URL but this particular method says go into my research directory, find all the Core Data models you can find, merge them into 1 model and that's where you're loading them into memory. So that was step 1, 1 line we covered.

Step 2 I said was create an instance of PersistantStoreCoordinator, here it is and set the model, right? So this is what we call the ManagedObjectModel accessor, that's step 2. Step 3 is to add the store to the coordinator so here we're telling it, add the store with the type SQL like and the URL is here, here's the URL which I just built beforehand so that's the end of step 3. And step 4 is to create a ManagedObjectContext. So here we have the ManagedObjectContext, I'll look it in it and here we set the coordinator on the context and that's it.

At this point you have the Core Data stack up and running and what do you do with that stack? Well this particular application I'm not going into the details of what the application is actually doing from a UI point of view but basically it creates a view controller which is going to handle all of the UI that has very little to do with Core Data and we pass it to context because that's going to be our main point of interaction with Core Data. And later on in the presentation I'll be showing you how you're interacting with the context but this is an Xcode template, that's how you set it up, right? The second important file that you want to look at from Core Data's point of view is your model file.

So here we have the Core Data model. It's a very simple 1 entity model. You'll be editing it as you expand your data, this definition. We have an editor inside of Xcode that allows you to do basically a relationship editing tool here. This is where you'll be creating future entities. Let's say that you want an event.

In addition to the event entity you want to have a location entity and you want these 2 things to be related so the event points to a location and the location has many events. This is the To-Many relationship. I'll be talking about these concepts in the presentation but I just want to show you how you would build your data description in a graphical way. Another thing I want to point out here is when you do have your model from Xcode you're also able to generate the files for these classes, for these entities, by going to the new file menu item. Here you have a file type, I'm sorry, in NSManagedObjectClass.

I'm going to create the files for the two entities that I have in my model and here they are. Here's the event entity. I just want to highlight here that we're not generating a lot of code. All of the implementation is coming from this class NSManagedObject which I'll be talking about in the presentation. We're simply declaring your accessor so that you can message them at run time.

If I go to the location 1, the location clause, really all I'm doing is declaring the accessor methods to add objects to that To-many relationship I declared. And look at the dot M, there's really nothing much there. This is where you would be introducing all of your specific business logic code but not really Core Data code that you need to implement. So we're not just dumping a whole bunch of code for you to work with. So that's a quick overview of the Core Data template that we have in Xcode. Now let's start going deeper into each one of those elements that I brought up in the demo.

So let's talk about modeling your data. The model, as I showed you in that file, has two purposes. The first is to describe the structure of your data, that's where you're defining your entities and how they're related and this is what we're using to create the store file for you and to manage it subsequently. But as you're defining the model, you're also giving us hints within the model as to what are the semantics of that data? You can add simple validation rules.

You can tell us what happens when a master object is deleted from a relationship, so there's a little bit more to the structure in your data. There's also a little bit of rules as to how you want us to help you manage it. It's important that you spend time thinking about your model because this is going to be one of the central elements that Core Data uses to help you out. So the better model you have designed, the more we will be able to help you. And try to design your model with the usage pattern in mind that you're going to give it in your application.

This is what a model looks like. Visually you saw it in the editor I just showed in the demo. At a very high level, this is by the way a model of a music domain where you have songs that are part of albums and albums are produced by artists, so just some vocabulary. The big boxes, we refer to those as entities. Entities are made up of property, you have properties.

They can either be attributes or relationships and there's something I'm not showing here in this diagram but there's also rules about the model encoded. So let's look at each one of those elements of the model. So entities are represented in run time by NSEntity descriptions but you probably don't have to worry too much about that. The entities are the blueprints that we'll be using to create the instances of your data.

They're made up of properties, attributes and relationships. So most of the time you'll be modeling all of the simple fields that you want us to store on your file but you should also know that some of the properties that you define in your model won't necessarily be persistent. They will be important to you at run time because you're dealing with that data but that data might not be persistent in that shape and form.

It might be a computed value from two other persistent properties so you can also model properties that aren't persistent and we call those transients. To make a database analogy, these are equivalent to table definitions with one important distinction. Even though there's a database behind the scenes you don't worry about primary keys because we're dealing with all of that for you, right? So don't try to model properties that represent primary keys in your data. Simply model what your data is. Don't worry about the underlying database constructs that you're not going to see. Entities are made up of attributes.

These are the simple fields that indicate the value type. You can see the types that we support, numeric, strings, dates, binaries but we also have this special type called transformable which can basically transform any other type that's not one of the basics type that we support, a color or a sound, and we can package it, as long as you give us a value transformer, we can package it into 1 of our basic types so if you don't see the type you want to have up there, you can still work with it. It just has to be wrapped up. As I said before the attributes also is where you start adding simple validation rules.

Say for example you're modeling the age of a person, within the model you can declare the range of values that makes a valid age, whether it can be null or not. The analogy here in the database world, these are column definitions. Finally, relationships are the properties that reference other entities.

They can either be To-One or To-Many. This is something that confuses initial uses of Core Data. In Core Data, relationships or To-Many relationships are modeled as unordered sets. So you're responsible for adding order To-Many relationships and it's possible but by default Core Data simply represents them to you as unordered sets.

We want you to model the relationships in bidirectional ways to have inverses so that we can better maintain the integrity of your data. And in terms of semantics at the relationship level is where you can tell us, you can give us hints as to what to do when deletion happens within your data.

So the master object goes away so what happens to all of the detail objects that are associated with it? These are equivalent to joint tables and foreign keys, except that they're not from your point of view because you don't worry about this, right? From your point of view they're just the concept that an entity is related to the other entity and you let us worry about how we're actually maintaining that relationship behind the scenes.

Don't model the joint table. So revisiting the model now that we're familiar with the terms, we have a basic music model that has a songs entity. The songs entity has four attributes. It has one relationship, the album. So a song has one album. It's a To-Many relationship to the album entity.

That relationship has an inverse which happens to be the songs relationship from album to songs. It's a To-Many because an album can have many songs and so forth. There's many To-Many relationship between album and artist and its model is many To-Many with an inverse of each other there.

So we're done talking about the model. Now let's talk about how you work with the Managed Objects. So here's the stack again that I introduced in the first section. In this part of the talk I'll be focusing on the context and the Managed Objects which is what you're really, that's your data.

That's what you want to manipulate. So your data will be represented as instances of NSManagedObjects. Each one of these represents a row of your data and this is really the workhorse. This is what you'll always be interacting with. They have to be associated with a single entity of course because they represent a row in each 1 of your tables and you also have a unique identifier.

I said before that you don't worry about the primary key and you don't but if you need to ask it's object for a unique idea, we do wrap that private key behind the scenes into an object wrapper so that there is a way of referring to the object with a unique ID. How do you interact, this is where it starts to get very interesting, how do you interact with your managed objects? You interact with them as any other Objective-C objects.

Simply call their accessors, right? We're doing all the hard work behind the scenes. You just start calling their accessors. The accessors are most likely going to be represented as Objective-C properties and remember that To-Many relationships are sets so you set mutator methods that you're interacting with To-Many relationships.

But most likely you're probably just going to be using the accessor methods that are generated for you, like I showed you in the demo. Now in the demo I showed you how to generate the code for your objects but that's not really necessary. I just wanted to show you with an Xcode where you go to generate the code. But by default unless you're doing your own custom logic in your objects, you don't need that.

You don't even need to have executed that step The default implementation of Managed Object already gives you support for key value coding, key value of serving so if all you're doing with your objects is setting their state and getting their state, you're not doing computed values or anything like that, you don't even need code for your objects. You already get that from the default implementation.

You would usually generate the code and extend their behavior if you want to compute the right values or you want to add multi-property validation and as I showed you in the demo, it's the new file menu, NSManagedObjects Subclass, where you actually go to generate the code if you need it.

So the objects, you create them but they don't exist in a vacuum. As I keep bringing up, you're always dealing with an object graph so objects always have to be associated with a context. It is the context, that's why they're called ManagedObjects. Who's managing them? The context is managing them. The context is the one that's keeping track of all the changes that you're performing on your objects so that when you tell us to save we know what to update in the file. So objects must always be associated with the context.

This is a weak reference between the two. Neither retains each other so you're responsible for retaining your own ManagedObjects if you want them to keep around. And the contexts are serving all the changes that you're performing in your objects. Think of the context as a workbench or as a scratch pad where you bring in all of your objects and you start interacting with them and Core Data is monitoring them and then you tell us to save and then we know what happened to maintain your object graph in a correct state.

Another way of thinking about this is if the objects represents the noun, the context defines the verbs that you want, you can execute on these subjects. So the context is what you'll be doing, things like fetching, inserting, deleting, saving and while you're doing all this, and updating to, your objects, the context will be keeping track of what's going on. So this is better explained in diagram form.

I'm going to walk you through a series of diagrams that show you how you interact with a ManagedObject context in your Managed Objects and what's going on behind the scenes with Core Data. So let's say that you already have a context set up that has an album and two songs and what you want to do is insert a new song on the album. So from your point of view, one line of code to create and instance of an object and I'll look in it, you create your instance of your object.

You always have to associate it with a context so part of the initializer for your managed objects requires a context so that's still in that 1 line of code. Now it's associated to the context and you want to add it to the album. As I said at the very beginning of this talk, you're simply interacting with objects and all that you're doing is calling their accessor methods.

So you can either, remember that we have a bidirectional relationship, so you can either set the album on the song by calling the set album accessor method or you can add the song to the album by calling the add song accessor method on the album. You can just do it on 1 side of the relationship. Core Data takes care of maintaining the integrity.

So that was 2 calls for you, right? You create the object and the second call is you give it an album and Core Data maintains that graph for you. Now you want to delete 1 method call for you, at the ManagedObjectContext level, delete and you pass it the instance of the album.

That's it, 1 method call. But this is where we start taking advantage of the information that you gave us in the model. If you told us to cascade your deletes, Core Data is also taking care of getting rid of all those songs for you. Oops, that's not what I wanted to do.

I changed my mind, undo, use the undo manager associated with the Context and we bring it back. We have, we're doing all this work for you, right? I know for you it's only 1 line of code for whatever you're trying to do with your objects and so forth.

As you continue to work with your objects to associate them, all you're doing is calling accessors on them. Let's say that you want to move song Q from album to album 2, all you do is call set album and pass the argument album 2 on your song instance and that's it. Core Data knows that the song has to be moved to the other album.

It has to be removed from the previous add and the To-Many relationship and album 2 has to be all set up. So this is where the power of the model comes in to play. You are only worrying about calling your access of methods as if these were a regular Objective-C object, which they are.

So that was a quick example or a series of examples of how you are interacting with objects as you're inserting them into the context or associating them with the context. Now most of the time, especially in the iPhone, the iPhone doesn't really lend itself to a lot of data entry, although you could do that, you'll probably be doing a lot of data fetching from data that you already have in a store.

So in this part of the talk I'm going to explain to you how you get your data which exists in the database, into the context. To accomplish this you will be creating an instance of a Core Data class called NSFetchRequest. This is really the query description. You're going to create your query description.

You're going to execute that query on the ManagedObjectContext and Core Data is going to take care of going down to your database, fetching the corresponding data, wrapping it as objects and presenting it to you as part of your object crash. And then from this point on it's exactly the same thing we just finished talking about.

These are objects and you interact with them by simply calling their access of methods or you execute methods on the context if you want to do more fetching or deleting or things like that. So let's look at the fetch request in more detail. The fetch request hasthree main elements that you have to set when you want to specify a query.

We need to know the entity that you're querying on, we need to know how you want to filter that information with a filter predicate and a sort descriptor, how you want us to sort that information when we bring it back. In database terms, the entity part of the fetch request is where you're indicating the select from clause of your query, but you're simply giving it the entity name.

The predicate is equivalent to the where clause in SQL land and the sorting descriptors are the order by part of the clause, right? So it's very similar to how you're doing the queries on the database except that it's got an object wrapper to it. Here are two quick examples of two very common fetch requests.

The first one I just, it's so simple but it confuses some people the first time they try this, what if you want to fetch all the artists? You simply create a fetch request saying the entity I want to work with are my artists, that's my artist and you don't give any predicate because you want all of them. And then you specify how you want to sort them and at that point you execute on your context and Core Data gets all of the artists in your database.

So this is probably 1 of the first things that your application will do as it wants to bring up its table view or whatever, initial display of data. Predicates can get very sophisticated. In this second example we're creating a fetch request that goes out and fetches all of the albums that have at least ten songs associated with them. So again what we want to work with are albums.

Our entity is an album, the predicate, we're walking the relationship songs on each one of those albums and we're taking a count of how many songs each album has and we're only returning the ones that have more than ten songs and then we sort. I'd like to highlight here, if you're thinking in SQL terms, this is where you would start thinking in terms of joint tables and putting two things together.

I'd like to highlight here that you're telling Core Data to fetch albums for you and you're specifying in the predicate that you want us to analyze your relationships and count how many objects are at the end of that relationship and give you back your results. So sure behind the scenes there are joints happening and Core Data is doing all of that for you but you don't have to worry about that. You're simply specifying your query in sort of more object level terms.

Now how much data are we actually bringing in each time you fetch? If you indicate a fetch to get albums or a subset of albums, we give you the albums. They're brought into the context. You might wonder well but you keep saying that we always have an object graph, right? So what happened to the songs that are part of this album? Well they're there in your database and Core Data knows about them. There's a little bit of bookkeeping information but we don't bring them into memory because you did not ask for the albums.

We simply brought albums in because that's what you asked for. So how do you get to the, I'm sorry, how do you get to the songs? Once again you simply message your accessor method. Let's say that you want to get to the songs in album 2, you have your album 2 instance and you call songs.

And Core Data behind the scenes, goes out, fetches the corresponding data and presents to you the result of the accessor method. So you don't have to create a secondary query and figure out which songs are related to this album. Core Data is taking care of this for you. So this is how you interact with traversing your Object Graph.

You start out with an initial object and depending on what your user is requesting from you, you simply call accessor methods on those objects and Core Data starts to populate the Object Graph behind the scenes for you. So as you can see this is where memory efficiency starts to come into play because you're only getting what you're touching as your walking object graph. We're also taking care of uniqueing so if you access the artist for album 3 and later on you access the artist from album 2 and it happens to be the same artist, Core Data is returning you a single instance of the artist.

So we're taking care of all of these things for you. If you're tried to do this in SQL by hand you probably are starting to realize now how much work there is behind the scenes when we're giving this to you. Now since you'll be doing so much fetching, potentially in your applications, you might want to think a little bit about how you are actually using the results that you're asking us to fetch, when you want to improve the performance of your application even more.

Are you actually using those objects that you got, you asked us to fetch? Are you just counting them to update a little field on your UI or do you even need full objects? Do you always happen to require all of the related objects once you fetch a MasterObject? And Core Data gives you simple ways of improving your fetch performance. This is a simple fetch, we're fetching a subset of albums like I just described in the previous slides, as I said, you asked us to fetch albums. We only fetch albums.

And we have a little bit of bookkeeping information to get the songs but they're not brought into memory. But let's say that the reason that you're fetching these albums into memory is just to count them. You're not even going to display them in the UI. In that case, be aware that there's a method on ManageObjectContext where you pass it a fetch request and we do all of the counting for you in the database and we don't even bring objects into memory if you don't want to take that hit.

So countForFetchRequest is a method that you can call on ManageObjectContext to go and get accounts for an object. So 1 little tip, for this particular use case you can avoid a lot of memory. Moving on in the same theme, let's say you have a part of your UI that only displays a subset of the properties in your entity.

You happen to define an entity with twenty properties and that's useful for other parts of the UI of your application but you have this little table view where you're only displaying one or two properties for that album so you don't really want to fetch the whole object if that's your primary fetch.

There's a method on NSfetchRequest setPropertiesToFetch where you indicate an array of the property that you want us to go get and when we populate your objects we only bring in the subset of properties that you're after. So again you're saving memory. If you later on need to message all the other property that you didn't fetch, no problem. You simply call your accessors. You don't worry about this. Core Data goes and fetches the full object for you once you actually need it.

This is now the opposite extreme of this case, this is an instance where you're fetching albums and you know that anytime you're fetching an album you will right away be dealing with the songs inside those albums. So you want to avoid the double trip to the database to first fetch the albums and then to go fetch the songs. So there's a method on NSfetchRequest where you can set the relationships keypass to prefetch so that we can go into 1 database strip, get your songs and your albums and save trips to disc.

Fetching in batches, let's say that you ask us to fetch a list of albums but then your user starts clicking in the UI to access them and they're kind of at random order so they first click in that upper set of albums and then they go to the bottom and then they go to the middle. But you asked us to fetch all the albums, right, so you're keeping all of those albums in memory. There's another way of indicating, of optimizing your fetch request by setting their batch size.

So in this particular use case you would say, you know what? I want you to fetch the albums based on this query but set a batch size of three for example. So we go and fetch, even though we know the list of albums that you asked us to get, we don't bring all of them in. We only bring in the first batch of three albums. It's an array. And then you access objects farther down in the array and Core Data realizes that they're not in memory yet.

We go and get the next batch, right? You move back up in the array, Core Data says those objects aren't in memory yet, we go and get the next batch. But here's where it gets very interesting. We keep a limited set of batches and we order them by least recently used so as we see that you're no longer using certain batches, they go away behind the scenes. We're getting rid of that memory. You don't have to worry about this.

So there's a lot of these kinds of things that you can learn by reviewing the NSFetchRequest header and documentation. What I'd like to point out right now is that all of those examples I just walked through, each one of those cases are simply one line of code for you. It's one setting or one flag that you're setting on the FetchRequest and you're getting a lot of performance behind the scenes with Core Data.

Moving on to working with UIKit, now Core Data deals primarily with the backend part of your application. We're helping you manage your data and persist it into a file. So what do you do when you want to display those objects in your UI? Core Data does not provide to you any UI classes that belong to the UIKit but since these are regular objects, regular Objective-C objects, you can use any standard UIKit class to display your objects. So don't think of Core Data objects as any different than whatever objects you're already dealing with when you're displaying your data on the iPhone. They're simply compatible with only the UIKit classes. There are two things to keep in mind here to your advantage.

ManagedObjects implement key value of serving and ManagedObjectContexts send out notifications each time certain events happen so your application could register to listen to these things as they happen so that you know when your UI has to be updated. So you begin to observe an object or you register for notifications on the ManagedObjectContext and if something happens that updates your data and you want to be notified that your UI has to be refreshed, you will get that notification and that could be the trigger point for the updating of the UI. There is one UIKit class that we do give you a little bit more help with and this is the UITableView, which is good because UITableView is probably the most used UIKit class in iPhone development.

UITableView displays a list of data broken up into sections. And if you have used this object before you'll know that the main thing the UITableView keeps asking you to provide is it keeps asking you, how many sections do you have in your data and how many objects are in each one of those sections? Well we already know how to get a list of data for you because that is a fetch request, right? You can indicate a fetch request.

We get a list of data. So we added this new helper class in iPhone OS, it's not present on the desktop, it's called NSFetchedResultsController and it's meant to be a helper instance for your UITableView and data source methods so that we can quickly and efficiently help you answer those questions that the UITableView is requesting.

We talked about fetch request, fetch request indicate a predicate and a sort descriptor. When you execute a fetch request you're basically getting back a list of data so that's already half of what UITableView is asking for. There's your data, the only one extra piece of information we need from you is you need to tell us what the keypath is.

Basically what is the name of the property on your objects that we can query so that we know what section that object belongs to? If we have this simple piece of information we are able to traverse your data and collect all the section information for you. Basically count all of your objects and break them up into sections and then once we have that information you can provide it to UITableView but more importantly we not only compute this information we cache it in a little private file so that the next time your application launches you can quickly answer the questions of how many objects are in your TableView, how many sections, by using a fetchResultsController.

So FetchResultsController is meant to be used when you want to cache section information. When the description and the definition of what your sections are isn't changing very often. So we assume that your FetchRequest and your predicate from this point of view are immutable things. If you're constantly changing the predicate that you're using to filter your information through or the elements, the entity that you're fetching on, you're probably not going to be getting the cache results of FetchResultsController because we still have to walk your data once, the first time around to calculate the section information.

So as long as you want to keep working with that data, we're able to help you out. Oh and by the way, we do register for notification. So as you modify your data set, we do update your session and information so that it's ready to use later on. Let me go to the second demo so that you get a better idea of how a FetchResultsController is used. So here's a pre-built application.

Let me first show you what it does, let me hide this. This is a simple application that goes out, connects to the Internet and parses the iTunes RSS feed of top songs. So Core Data does not parse feed RSS feeds out on the Internet so that part of the application is not Core Data but when it does the parsing, it imports all of that data into a local store file so that you can access those objects when you don't have an Internet connection. That part is Core Data.

So we basically create a Core Data store and then we used that do display the UI. Once we displayed the UI we can display the songs in two ways. Here we sort them simply by rank so here are the top 3 songs, the top 300 songs sorted by rank in a TableView with one single section or we can break them up into sections by the name of the category that the song belongs to so Jazz, Holiday and whatever other categories we have, Hip Hop. So in these two cases we're using two FetchResultsControllers to help us out, one of them is configured in a single section mode and the other is configured in a multi-section mode and I'm going to show you the code of how that is done.

Let me just run this here again. So again I'd like to highlight here that this is an application that uses Core Data. Parts of the application, like in many applications, have nothing to do with Core Data. They have to do with parsing fees and displaying data on the UI but in parts of the application you're relying on Core Data to help you out with a data persistency part.

So if it's an application that uses Core Data, let's just review. We probably have methods to set up the stack. So here we have the method to create the ManagedObjectsContext and to set up the PersistantStoreCoordinator. I'm not going to go into those. I showed them in the first example but they have to set up the stack, right? If this is an application that uses Core Data then you'll probably have a model.

Here is your model, songs and categories. When your application sets up the Core Data stack, the first thing it does is that it creates this secondary class here, iTunes RSS importer. This is the code path that takes care of parsing the RSS feeds and creating a Core Data store for that data.

So within that class, let's just quickly jump into that class, most of this code has nothing to do with Core Data. I just want to highlight there's a little part in that code where you are creating instances of songs as you're parsing them from the feed. So this is kind of the Core Data part where you're creating a song, your associating it with an entity and a context.

There's other methods in this class where you're actually setting state on the song. And finally this is the part of the application that is displaying the UITableView. Again, most of this has nothing to do with Core Data. It's simply UIKit code. It implements the delegate and the data source method for TableViews.

But in these methods when you're trying to answer the questions, how many sections are in your data, in your TableView, you are using this helper instance FetchResultsController, you're asking it to give it to you in sections and then you're giving the count of that section. So you are quickly able to answer the question, how many sections are in my data set by asking the FetchResultsController and likewise you're able to figure out how many objects are in each 1 of those sections by also using the FetchResultsController.

So let's see how we can figure that FetchResultsController. We said that a FetchResultsController required a FetchRequest. Here we are. We create a FetchRequest. A FetchRequest requires an entity, we give it a song. In both cases, in both kinds of sorting, we're always displaying songs and the only thing that differentiates these two instances is in this case I'm sorting by rank and I don't have any sections and in this case I'm sorting by categories and the sections are broken up by the name of the category.

So here we initialize instant nil and we have an IF statement depending on which case we're configuring. Here we're configuring the case where we're sorting by category so we create sort descriptors where the primary sort is on category name, the secondary sort is on rank and the section named keypath is the category dot name.

So basically for each song that we get back from the database, we ask its category and then we ask the name of that category and that's how we can tell what section they belong to. In the other case where we're simply sorting by rank, the sort descriptor is a rank, is by rank. Once we have that set up, we create the instance of the FetchResultsController, we pass it the FetchRequest we configured, the context and the section named keypath.

So this is all you have to do to set up the fetch and there's a method where you tell us to do the fetching but then from that point on all of your data has been fetched and broken up into sections and you can use that helper method to quickly help you populate your UITableView. So that was an example of how you get the benefits of using a FetchResultsController.

Now you might be asking yourselves, ok this is great technology but what's the catch, where's the cost? You're doing all this stuff for us behind the scenes, what's the penalty? Well we wondered that ourselves when we were doing the port to iPhone so one of the first things we did was to create a sample application that managed generic record data and we measured the launch time of this application when it has 10,000 records in its database. And we created multiple versions of the application. The first version of the application we created was very general SQL code, not Core Data. This is how you would be writing the application in iPhone OS 2.0, before Core Data existed.

And we measured that it launched in five seconds. So then we ported the application to Core Data on the iPhone to see how that would compare and we launched 30 % faster in 3.5 seconds because we now start taking advantage of Core Data faulting and partial fetching of your data. Not only that, we kept going. We added one line of code to do batch fetching and we're now launching 80% faster.

So I can tell you that when it comes to speed there is no penalty when we're using Core Data compared to a very generic SQL solution. Memory, what happens with the same application with its active heap size? The SQL application has 1800 kilobytes. Core Data did not grow more than the SQL application even though we're dealing with objects where we're wrapping all of your rows in your objects.

We have the context. You're not taking a hit on your memory. And when we enable the fetching, remember that slide where I show you how batches were disappearing behind the scenes when you weren't using them? We got a 50% improvement in memory use with 1 line of code.

Speaking of lines with code, we do a lot less database guard work right? So you have a lot of code in your SQL application in addition to your UI display code, simply dealing with pulling in that data and wrapping it into objects or dictionaries or however you want to deal with them in memory.

With Core Data we cut our code in half because we do all that for you. The framework takes care of that. You saw how we were able to set up the Core Data stack with four or five lines of code and you're using simple accesses on your objects to message your data so we got rid of a lot of code that was dealing with the backend part.

When we enable fetching [laughter] our code size grew by one line so yes we did take a hit of 1 line but you saw in the previous slides the huge performance impact that you get by enabling all of the flags that we have in your FetchRequest as you start adopting to your data set and how you're using it.

So there's a lot more to talk about Core Data and I encourage you to go to tomorrows session to learn more about the technology and what's new in 3.0 but I do want to highlight a couple of points here before leaving you. One is, well what do you do with your preexisting data? You already have your database in some format, a PLIST or SQL database.

Remember that Core Data owns the store file both for creation and maintenance. So we, even though behind the scenes the file might be SQL, the implementation is private to you guys so we don't want you to go behind the scenes and update the SQL yourself, ok? So please don't touch the Core Data file.

Always use it from Core Data's APIs downward. So what we ask that you do if you have a preexisting data set, is that you add an import step so that you can parse your data and create a Core Data store and save the context and then from that point on you have your data in Core Data format and then we can help you better interact with it.

There's a good part of the documentation, the Core Data programming guide explains to you how to do efficient importing, especially if you have large datasets and we actually have a lab on Thursday that walks you through how to do importing from a generic SQL database into Core Data. So Tuesday at noon if you want to look at that we have sample projects set up on a little thing that you can spend time experimenting with.

The second thing that I want to highlight because you're going to run into this very quickly, you saw how in that first demo how I launched the application? I created a little bit of time stamps and then I quit the app and there was already data in the database, in the store file and then the next thing I did was I started modifying the model. If you try to follow at home, after you modify the model and you launch the application again you will get a launch error and what's going on there is that you have preexisting data in your database and you change the model. So you break the contract.

We're not allowed to open your database because we don't really know the structure of that data when you have given us an updated version of your model. So just be aware that if you open a store with an incompatible model, you will get an error. How do you know you're getting an error? In step 3 of setting up the Core Data stack where you're adding the persistent store to your coordinator, that call can return false or no and when you print out the error and you see something like this, the model used to open the store is incompatible with the one used to create it, you know that you're in this situation.

You're basically pointing us to a model, you're giving us a model that is not the same one that you use to create the store that you have on your file but don't despair, there's ways of working around this. I just want you to know that this is what's happening if your application is not launching the second time.

So what do you do once you're in contact this error? First be aware that if you're working with throw away code you're simply experimenting. The easiest way for you to work around this error is to simply get rid of that store and relaunch the application. You don't care about that data How do you get rid of the store? In the iPhone you can just delete the whole application and then the next time you launch it, it will create the store from scratch. Or you can go into your iPhone simulator preferences or documents directory and delete the store there. So the throw away data, just get rid of it and launch again as you experiment with Core Data but of course this is not a scalable solution.

At some point you're going to have data that you care about, we again help you there. We have ways of migrating your data, we have two ways. We have another kind of model file that you also edit in Xcode. It's a Core Data mapping model where you tell us how to get from version A to version B of your data and then we have a very sophisticated migration infrastructure that basically opens up your store and moves all of your data over and saves it in the new format. And in Snow Leopard and also available on the phone, we have a new kind of migration which we call lightweight migration where we try to be smart about figuring out that your data changed for certain kinds of changes and we do the migration for you.

So there is help there. Please check the Core Data migration guide to learn more about that. Another thing is I've been showing you this Core Data stack, we have a store and a coordinator and a context. It's not the only way that you can set up the stack. Core Data's are very flexible technology. You could have multiple stores behind the scenes. You could be pointing to multiple files. Some of your files could be read only, look up tables.

The other 1 could be the 1 where you're actually doing your edit so that's why it's called a coordinator because it's coordinating how ever many connections you have behind the scenes. You can also be doing multiple edits like a master edit and a detail edit so you can have potentially multiple ManagedObjectsContexts that you're interacting with and those 2 things are not related.

You don't need to have multiple stores to have multiple contexts so look into the programming guide of Core Data. I just want to highlight here that there's many ways of setting up your Core Data stack depending on how sophisticated your application is. Finally remember that we are on our third release of Core Data.

This is a very mature and stable codebase. With regards to the desktop, the store file formats are the same. You can move them from the phone to the desktop. On the desktop you have 1 additional type, you have the XML store type which doesn't appear on the iPhone, just be aware of that.

And on the desktop you also have another technology, non Core Data, called Cocoa Bindings which helps you create the more sophisticated Cocoa UI's that you require in a desktop stack with multi-window and a lot more which is for Windows so there's Cocoa Bindings and there's an additional store type on the desktop but otherwise it's the same technology. This is not Core Data lite on the phone or anything.

This is Core Data. So if you have anymore questions please contact our evangelist, Michael Jurewitz and please check out our documentation. We have a ton of documentation. We have programming guides, examples, tutorials. We just posted a whole bunch of new examples in the developer forums yesterday. There's so much in fact that we need a starting point overview document so if you start out, look for the Core Data overview document and it's a little one or two page document that points you to the right direction based on what you want to learn about Core Data because there's a lot of documentation.