Tim Isted Tom Harrington

Core Data for iOS Developing Data-Driven Applications for the iPad®, iPhone®, and iPod touch®

Upper Saddle River, NJ • Boston • Indianapolis • San Francisco New York • Toronto • Montreal • London • Munich • Paris • Madrid Cape Town • Sydney • Tokyo • Singapore • Mexico City Many of the designations used by manufacturers and sellers to distinguish their Editor-in-Chief products are claimed as trademarks. Where those designations appear in this Mark Taub book, and the publisher was aware of a trademark claim, the designations have been printed with initial capital letters or in all capitals. Senior Acquisitions Editor The authors and publisher have taken care in the preparation of this book, but Chuck Toporek make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for incidental or consequential Development Editor damages in connection with or arising out of the use of the information or Chuck Toporek programs contained herein. The publisher offers excellent discounts on this book when ordered in quantity for Managing Editor bulk purchases or special sales, which may include electronic versions and/or Kristy Hart custom covers and content particular to your business, training goals, marketing focus, and branding interests. For more information, please contact: Project Editor Andy Beaster U.S. Corporate and Government Sales (800) 382-3419 Indexer [email protected] Larry Sweazy For sales outside the United States please contact: Proofreader International Sales Jennifer Gallant [email protected] Visit us on the Web: informit.com/aw Technical Reviewers Library of Congress Cataloging-in-Publication Data is on file. Jim Correia Copyright © 2011 Pearson Education, Inc. Robert McGovern All rights reserved. Printed in the United States of America. This publication is Mike Swan protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any Publishing Coordinator form or by any means, electronic, mechanical, photocopying, recording, or likewise. Olivia Basegio For information regarding permissions, write to: Interior Designer Pearson Education, Inc Gary Adair Rights and Contracts Department 501 Boylston Street, Suite 900 Cover Designer Boston, MA 02116 Chuti Prasertsith Fax (617) 671 3447 ISBN-13: 978-0-321-67042-7 Compositor ISBN-10: 0-321-67042-6 Gloria Schurick Text printed in the United States on recycled paper at R.R. Donnelley in Crawfordsville, Indiana First printing June 2011 iii

Table of Contents

Part I Introduction

1 An Overview of Core Data on iOS Devices 3 A Little History...... 3 The Birth of Core Data ...... 4 Why Use Core Data on iOS? ...... 4 Relationship Management ...... 4 Managed Objects and Data Validation ...... 5 Undo and State Management...... 5 Core Data iOS and Desktop Differences...... 5 The Fetched Results Controller ...... 6 Core Data Case Studies ...... 6 MoneyWell for iPhone ...... 6 Calcuccino ...... 7 Associated Press ...... 8

2 A Core Data Primer 9 Persisting Objects to Disk ...... 9 The Core Data Approach ...... 10 Entities and Managed Objects...... 10 Relationships...... 11 Managed Object Contexts...... 12 Fetching Objects ...... 14 Faulting and Uniquing ...... 14 Persistent Stores and Persistent Store Coordinators ...... 15 Examining the Core Data Templates ...... 15 The Navigation-Based Project Template...... 16 The Data Modeler ...... 16 Setting up the Core Data Stack ...... 17 Running the Application...... 20 A at the RootViewController Code ...... 20 Summary ...... 21 iv Core Data for iOS

3 Modeling Your Data 23 Managed Objects and Entities ...... 23 Dividing Your Data into Entities ...... 24 Core Data in Model-Object Terms ...... 24 Data Normalization ...... 25 Storing Binary Data ...... 27 Working with Xcode’s Data Modeler ...... 28 Creating Entities ...... 29 Creating Properties ...... 31 Creating Relationships ...... 35 Summary ...... 37

Part II Working with Core Data

4 Basic Storing and Fetching 41 Creating New Managed Objects ...... 41 Saving the Context...... 42 Fetching Saved Managed Objects ...... 44 Deleting Managed Objects...... 45 Working with Table Views ...... 46 The Random Dates Application Project ...... 47 The Random Dates Data Model ...... 48 Basic RootViewController Behavior ...... 49 Fetching the Random Date Objects ...... 51 Displaying the RandomDate Objects ...... 52 Deleting the RandomDate Objects...... 54 Custom Managed Object Sub-Classes...... 54 Creating and Setting a Custom Class for a Managed Object ...... 56 Summary ...... 60

5 Using NSFetchedResultsController 61 Introducing NSFetchedResultsController...... 62 Creating an NSFetchedResultsController ...... 62 Supplying Information to Table Views...... 64 The Number of Sections and Rows ...... 65 Returning the Cell for an Index Path ...... 67 Returning Information about Sections ...... 68 Handling Underlying Data Changes...... 69 Caching Information...... 72 Using an NSFetchedResultsController in the Random Dates Application..73 Subclassing NSFetchedResultsController ...... 80 Summary ...... 85 Contents v

6 Working with Managed Objects 87 Basic Managed Object Subclass Files ...... 87 Creating the Random People Project ...... 88 Managed Object Class Interfaces...... 89 Managed Object Class Implementations ...... 90 Configuring the Random People Application...... 93 Displaying the Information...... 95 Data Validation ...... 99 Validating Individual Properties...... 99 Validation Based on Other Properties ...... 101 Validation Prior to Deletion ...... 104 Fixing the Random People Application ...... 105 Working with Transient Attributes...... 105 Modifying the Data Model...... 106 Adding to the AWPerson Interface and Implementation...... 106 Adding a Getter Method for the Transient Property ...... 108 Adding a Setter Method for the Transient Property ...... 110 Using the UIColor Property...... 111 Working with Transformable Attributes...... 113 The Managed Object Lifecycle ...... 114 Initializing Non-persistent Properties ...... 114 Summary ...... 116

7 Working with Predicates 117 Predicate Basics ...... 117 Creating Predicates Using Format Strings...... 118 Predicate Variables ...... 120 Predicate Comparison Operators...... 122 Key Paths...... 123 Comparing Strings ...... 124 Compound Predicates...... 126 NSCompoundPredicate ...... 128 Sets and Relationships ...... 129 Examining SQL Queries...... 130 Adding a Search Display Controller ...... 130 Setting a Fetch Predicate ...... 132 Modifying the Search Predicate...... 136 Adding a Search Scope Bar Filter...... 139 Summary ...... 141 vi Core Data for iOS

8 Migration and Versioning 143 The Migration Problem...... 143 Changing the Data Model...... 144 Multiple Data Model Versions and Lightweight Migration...... 145 Creating Data Model Versions...... 145 Enabling Lightweight Migration ...... 146 Renaming Entities and Attributes ...... 148 Supplying Renaming Identifiers...... 150 Keeping Track of Multiple Versions ...... 151 Mapping Models ...... 152 Custom Entity Migration Policies ...... 156 Summary ...... 160

9 Working with Multiple View Controllers and Undo 163 Editing Managed Objects...... 163 Keeping Track of the Managed Object to Edit...... 164 Updating a Managed Object’s Properties ...... 168 Validating Managed Objects ...... 171 Working with Undo...... 174 Multiple Managed Object Contexts ...... 175 Merging Changes from Other Managed Object Contexts...... 178 Changing Managed Object Values Whenever the Control Values Change...... 179 Resetting a Managed Object Context ...... 181 Using the Editor Controller to Add New Objects...... 182 Summary ...... 183

Part III Building a Simple Core Data Application

10 Sample Application: Note Collector 187 The Note Collector Application ...... 187 Creating the Note Collector Project...... 188 The Application Data Model ...... 188 Modeling an Abstract Entity ...... 189 Modeling Sub-entities...... 189 Creating Managed Object Class Files ...... 190 Configuring the RootViewController...... 192 Displaying the Contents of a Collection...... 195 Keeping Track of the Collection to be Displayed ...... 196 Examining the Contents of a Raw Data File...... 200 Contents vii

Setting and Editing an Item Name...... 202 Creating the New View Controller...... 203 Displaying and Editing ...... 210 Supplying a Pre-Populated Data Store...... 217 Working with a Data Store in the Application Bundle...... 217 Summary ...... 219

Part IV Optimizing and Troubleshooting

11 Optimizing for iOS Performance and Memory Requirements 223 Performance, Optimization, and Speed ...... 224 Data Store Types...... 224 Binary and Memory Data Stores ...... 225 SQLite Data Store...... 225 Monitoring SQLite Stores ...... 225 Optimizing Fetching...... 230 Setting Fetch Limits...... 230 Optimizing Predicates...... 231 Pre-Fetching Relationships ...... 233 Pre-Fetching Any Object...... 234 Pre-Loading Property Values ...... 235 NSFetchedResultsController and Sections ...... 235 Managing Faulting...... 235 “Safe” Fault-Free Methods ...... 236 Preventing Property Loading...... 237 Batch Faulting...... 237 Re-faulting Objects ...... 237 Managing BLOBs...... 238 Putting BLOBs in the Entity That Uses Them ...... 239 Putting BLOBs in a Separate Entity...... 240 Putting BLOBs in External Files ...... 242 Monitoring Core Data with Instruments ...... 245 When Not to Use Core Data...... 248 Other Memory Management Tips ...... 248 Don’t Use an Undo Manager If You Don’t Need It ...... 249 Resetting the Managed Object Context...... 249 Summary ...... 249

12 Troubleshooting Core Data 251 Your First Core Data Error ...... 251 The Missing Model ...... 254 Classes Not Found?...... 255 viii Core Data for iOS

Core Data Threading Issues ...... 257 Basics of Core Data Multithreading ...... 257 Coordinating Data Between Threads ...... 258 When Threads Collide, or Handling Data Conflicts ...... 260 Danger! Temporary ID!...... 264 Problems Using Managed Objects ...... 265 Crashing When Setting Property Values...... 265 If Custom Accessor Methods Aren’t Called ...... 266 Managed Object Invalidated ...... 267 Faults That Can’t Be Fulfilled ...... 268 Problems Fetching Objects ...... 269 Trouble Sorting Data During Fetches ...... 269 Fetch Results Not Showing Recent Changes...... 270 Summary ...... 270

Index 271 Preface

We live in a data-driven world. We consume social data, like email, Twitter, and Facebook, business data, like share prices, financial forecasts, and bank accounts, and occasionally we might have a little fun with the more recreational side to life, like brainteasers, or games involving squawking birds and mock air traffic control, where we expect to be able to track our progress and rejoice when we beat our previous high scores. As mobile devices increase in performance, capacity, and capability, we place ever-increas- ing demands on our phones or tablet devices to consume, save, fetch, search and display our data. Consumers buy , iPod touches and with storage capacities unheard of in handheld or even desktop devices only a few years ago, and they expect to fill those capacities either with media, or with applications and data. It’s increasingly difficult to imagine an application with any non-trivial functionality that doesn’t maintain at least some kind of data store. Even if a Twitter client maintains only a temporary store of downloaded tweets, it will at least need to keep permanent track of one or more Twitter account usernames for timeline refresh; applications have persistent memories for calculated values, or store a history of previous calculations; and, in order for us to feel a sense of achievement, games store a history of high scores, as well as a state of play so that we can return immediately to our gun-slinging 3D shoot-‘em-up just as soon as we finish our FaceTime chat. For us mobile app developers, the demands are high. Not only do users expect our apps to store data as efficiently as possible, they expect their applications to run quickly, smoothly, and without crashing. Given the relatively limited runtime memory capacities of these mobile devices, dealing with persistent data can quickly become a nightmare. Mobile devices also introduce the issue of power management, which is rarely a concern when writing software for desktop computers. An app that eats batteries will not please its users. When the iPhone SDK first launched, developers were left to fend for themselves when it came to data access. Data persistence was possible only via basic file storage, or through direct access to a SQLite database. SQLite can certainly help out with the limited runtime memory problems, but generally requires developers to fashion their own persistence layer to interact with model objects and generate the underlying SQL commands necessary to save and restore plain data. Core Data changes all that. From version 3.0 of the iPhone SDK (renamed to iOS as of version 4.0) onwards, Apple provides us with a ready-made data persistence layer. We define a schema for the model objects we want to store, then leave Core Data to figure out what to do to persist our model data to disk. We don’t have to worry about low-level SQL commands, or the memory meltdowns involved when loading 1GB of data from a single file. Instead we work with a “data store,” a term that is intentionally vague since details of managing data files are abstracted away. Developers are free to work with their objects and leave the file management to the framework. x Core Data for iOS

If is the sexy framework for views, we now have an equally sexy (though possibly less visually glamorous) framework to help us with our model. By taking away much of the drudgery of data persistence, we’re left with more time to work on the features and functionality unique to our applications. Core Data can be the perfect answer to many data-related prayers, but it comes with a steep initial learning curve. Because of its ability to work easily with a SQLite database for its storage, it’s often mistaken for a database itself and, although this is inaccurate, it certainly helps to have a basic understanding of general database terms and techniques. Although the number of Core Data classes is relatively small, it’s necessary to make use of most of them before you can do anything at all with the framework. It’s hard to under- stand terms like “managed object context” before you understand “managed object,” or “persistent store,” but in order to make use of a managed object, you need a managed object context, and a persistent store. Getting over the initial leap of faith in a basic Core Data stack can seem a sizeable obstacle in making use of the framework. This book teaches Core Data from the ground up. You’ll learn about these primary classes in the framework, seeing how they interact to provide amazing functionality with very little configuration and tweaking. You’ll find out how to store and fetch data, look at best practices for providing data to the staple view of many data-driven apps, UITableView, and discover how easy it can be to perform data validation to ensure data integrity. Finally, you’ll look at ways to troubleshoot your Core Data applications, or enhance data-related performance bottlenecks. By the end of the book, you’ll have a thorough understanding of the framework and its classes, and probably be left wondering how you ever managed without it.

Audience for This Book

Aimed at intermediate to advanced iOS developers, the book assumes that you have a reasonable working knowledge of programming iOS applications. In particular, you should be comfortable working with Apple’s basic developer tools (Xcode), the Objective-C language, and the Cocoa Touch framework. It is not assumed that you have already worked with Core Data on the desktop, although the vast majority of the information included in this book applies to Core Data in general, both on iOS devices, and under Mac OS X (10.4 or later). Once you’ve mastered Core Data on iOS, you’ll be able to use the same tools (Xcode’s data modeler) and much of the same code (with the exception of NSFetchedResultsController, which is iOS-only) to build Core Data applications on the desktop. Preface xi

Who Should Read this Book

If you write iOS applications, you’ll probably have data persistence needs. If you need to work with anything other than the most trivial data storage, you’ll likely find it easier to work with Core Data than to create your own file-based or low-level SQLite-based persis- tence layer. If you need to work with Core Data, you should read this book. If you’ve never used Core Data before, this book will teach you what you need to know to get started. Once you’ve mastered the fundamentals of the framework, including the iOS- specific NSFetchedResultsController, and walked through the construction of a complete Core Data-based application, you’ll find performance tips and troubleshooting information. If you’ve already been using Core Data for a while, and keep wondering why your app crashes when you work with large of model objects, or can’t figure out why you’re suffering a performance hit in certain situations, this book will help clear up any mysteries with the fundamentals of the framework, and help you use Apple’s developer tools to isolate the sources of those problems.

Who Shouldn’t Read This Book

Core Data is definitely not the easiest to understand of the Cocoa Touch frameworks. If you’ve never created an iOS application before, or struggle to remember the difference between a UIView and a UIViewController, you’ll have problems working through this book. Although the first few chapters aim to flatten the learning curve as much as possible, it’s assumed that you have a solid understanding of both the Objective-C language, and the Cocoa Touch framework. If you don’t, you’d be better looking at a suitable introductory iOS programming book. It’s also worth noting that Core Data is commonly mistaken for a database. Although Core Data can use SQLite, it’s not by any means a SQLite wrapper nor is it designed for typical database usage. If what you really need is a database, Core Data may not be the right solu- tion and this book might not be appropriate. Finally, if you’re looking for creative visual interface inspiration, or suggestions for stun- ning data representations, you might prefer to look elsewhere. The sample applications in this book are specifically designed with interfaces that are as simple as possible to help you learn the Core Data framework with minimal distractions. For this reason, all the sample projects are for iPhones or iPod touches, and don’t include iPad-specific resources. Equally, if you’re looking for tips to beautify table views or design jaw-dropping custom views, you’ll likely be disappointed. Do bear in mind, however, that just because many of the sample projects in this book make use of the more traditional data display controls (i.e., table views), you can use Core Data in any situation where you need easy and efficient access to data. Need to store a list of high scores to draw in an OpenGL view for a game? Core Data makes that easy (well, the storage part anyway). Need to store enough information to draw icons that represent the weather for the 24 hours? Core Data can help with that too. xii Core Data for iOS

What You Need to Know

The book also assumes that you’re familiar and comfortable with Xcode and programming in Objective-C. You won’t find any primers on how to define a method, or how to install and launch Xcode; there are plenty of entry-level books for newbies and converts from other platforms and programming environments, and if you’re messing around with data models and such, we can assume that you’ve already got that grounding. As with any iOS development, you’ll need at least a free account. To test your applications on real devices, or sell on the , you’ll need a paid iOS devel- oper account ($99 per year at the time of writing). Go to developer.apple.com/ devcenter/ios to register for access to all of the relevant updates for iOS, as well as Xcode, developer documentation, sample code, and even the session videos from Apple’s annual World Wide Developer Conference. Without a paid account it’s still possible to develop iOS code, but you’ll only be able to run this code on the iPhone Simulator. While the Simulator is extremely useful, it’s no substitute for getting your code on a real iOS device. Core Data can support a number of different persistent store types, the inner workings of which it mostly hides from the developer. By far the most common type on iOS devices is the SQLite store, which saves persistent data into a SQLite database. You don’t need to know anything about SQLite to read this book, but if you’re already a database super-user, you’ll probably know that there is some controversy about the pronunciation of SQLite. D. Richard Hipp, the creator of SQLite, pronounces it “like a mineral”, pronouncing Ess- Queue-Ell-Ite as one might pronounce “pyrite” or “kryptonite”.1 Hipp does not insist on this pronunciation though, and in practice the vast majority of Mac and iOS developers we’ve encountered pronounce it Sequel-ite. For this reason we’ve chosen the latter pronunciation, so you’ll find we talk about “a SQLite store” rather than “an SQLite store.”

How This Book is Organized

The book offers a comprehensive discussion of Apple’s Core Data framework as it applies on iOS devices, building a firm grounding in the subject before covering more advanced and real-world examples of its use. Many of the chapters in the book are divided into two parts—you start by learning the relevant information, and then cement your understand- ing by putting the knowledge into practice with a sample project. Chapter 10 walks you through the complete construction of a Core Data-based note taking application, from start to finish. If you want to jump straight in and find out what’s possible with Core Data, you might like to begin with Chapter 10 to whet your appetite, then return to the beginning of the book to find out how it all works.

1 Hipp discussed “SQLite” pronunciation at the C4[2] conference in September 2008. His presentation can be viewed at http://www.viddler.com/explore/rentzsch/videos/25/ Preface xiii

. Part I: Introduction Apple’s Core Data framework presents a unified and powerful solution to storing an application’s data. This book offers a comprehensive reference for the framework and its use in versions of iOS from iPhone SDK 3.0 onwards. As well as covering Core Data basics, this section discusses more general topics like object modeling and data persistence, and demonstrates how to build an object model using Xcode’s data modeling tool. . Chapter 1: An Overview of Core Data on iOS Devices This first chapter introduces Core Data as a framework to fit into the MVC- pattern for development of applications for iOS. It gives a brief outline of its history as the Enterprise Objects Framework for web development, before discussing when, how and why Core Data is useful. It explains how there is little difference between working with Core Data on the desktop and on iOS, with the notable exception of the lack of support for Bindings on iOS. The overview finishes by showcasing a few real-world examples of Core Data use in publicly-available iOS applications, including MoneyWell for iPhone, Calcuccino and the Associated Press news application. . Chapter 2: A Core Data Primer Having given a high-level overview in Chapter 1, this chapter delves deeper and introduces the key features in Core Data, covering the interaction between Managed Object Contexts, Managed Objects and the underlying Persistent Stores. It also introduces the framework classes behind these and explains how impressive functionality can be achieved with very little code, often without the need to subclass the basic framework classes. The chapter continues by explaining the process of writing applications that use Core Data. It concludes by taking a look at what is happening behind-the-scenes in Apple’s Xcode template projects for Core Data iOS applications. . Chapter 3: Modeling Your Data This chapter introduces general ideas behind data modeling. Having expressed clearly that Core Data is not in itself a database, the chapter does discuss basic relational database techniques and relevant best practices (for example, data normalization that applies to object model design). This chapter also explains how data stored in a relational database can be mapped into a relational object model for use in object-oriented programming languages and concludes with a demonstration of how an object model is defined for Core Data using the Data Model editor in Xcode. . Part II: Working with Core Data The second part of the book focuses on a discussion of topics that apply to most applications wanting to make use of Core Data on iOS. Each facet of the framework or its related technologies is given a separate chapter so it is possible either to read this part of the book in order, building knowledge in incremental steps, or to pick xiv Core Data for iOS

out the chapters that are of particular interest. Each of these chapters is divided into two sections: the first introduces the particular feature or functionality, discusses why and when it might be useful, then walks through the relevant classes and methods; the second section is written in a tutorial format that starts by adding a basic feature to a simple application, before building on more advanced functional- ity. The aim of these tutorial sections is to enable you to learn by doing, but in such a way that you relate the same techniques to your own applications. . Chapter 4: Basic Storing and Fetching This chapter guides you through the process of building a simple iPhone appli- cation that uses a UITableView to display managed objects. It includes more information about managed object contexts, and how they relate to the under- lying data—a good understanding of managed object contexts is absolutely fundamental to using Core Data effectively. This chapter explains what contexts are, how to use them, where a context ‘comes from’ and how they interact with each other and the data store. The project for this chapter features a simple Add button to add objects that are fetched and displayed in a table view; to keep it simple for now, each object is pre-populated with randomly-generated information. . Chapter 5: Using NSFetchedResultsController This chapter demonstrates how to make use of the Fetched Results Controller, an object unique to iOS, to handle much of the functionality necessary to fetch and display objects in a table view. It explains why memory usage is so important on iOS, and how a fetched results controller works to keep to a minimum the number of objects held in memory at any one time. . Chapter 6: Working with Managed Objects

This chapter introduces the functionality provided by NSManagedObject, such as basic data validation. Although it frequently isn’t necessary to subclass NSManagedObject, this chapter explains why, when and how to do so. You’ll learn about the lifecycle of managed objects, and look at different types of modeled properties. The chapter covers features offered by Objective-C 2.0 to simplify accessor method code and finishes by looking at custom validation logic. . Chapter 7: Working with Predicates This chapter begins with the basics of creating an NSPredicate, discussing simple predicate format strings. You’ll learn how to use predicates to match against scalar values like numbers or dates, and also how to match objects, particularly across relationships, such as when fetching employees who work in a specific department. There’s a whole section dedicated to working with strings, including information on case sensitivity, and you’ll see how to examine the raw SQL that Core Data generates to query a SQLite store. Preface xv

. Chapter 8: Migration and Versioning This chapter looks at how to use the provided versioning and migration func- tionality to maintain compatibility between old and new versions of an appli- cation’s data model. By default, an application built around a newer model version won’t be able to open an older version’s model; through using auto- matic migration, the user can continue to work with their old data even after an application upgrade has occurred. You’ll learn about both simple migration, where the Core Data framework itself works out how one data model version relates to another, as well as custom migration using mapping models and entity migration policies. . Chapter 9: Working with Multiple View Controllers and Undo To keep the examples as simple as possible, and to minimize distractions, the previous projects up to this point have made use of only a single view controller. In this chapter, you’ll see how to keep track of managed object contexts across multiple view controllers, and how to use editing view controllers to change values on existing managed objects. You’ll learn how to work with multiple managed object contexts, and find out how to refer to managed objects across these multiple contexts, before finding out how simple it is to make use of the automatic Undo functionality provided by Core Data. . Part III: Building a Simple Core Data Application The third part of the book takes the reader through building a complete application using Core Data. . Chapter 10: Sample Application: Note Collector This chapter puts your Core Data knowledge into context by walking through the creation of a more substantial application than you’ve worked with so far. You’ll see how to work with abstract entities, entity inheritance and multiple view controllers to create a fully functional note-taking application that stores notes and organizes them in collections. You’ll learn how to examine a raw SQLite file to peek at what Core Data is doing, and find out how to include a pre-populated data store so that users of the application see some sample data when they launch the application for the first time. You’ll also look at one way to persist application state across launches, seeing how to archive the managed object information necessary to recreate a navigation-based stack of view controllers. . Part IV: Optimizing and Troubleshooting The final part of the book looks at performance issues, optimization for the restricted memory requirements of iOS devices, and at debugging tools to aid in developing with Core Data on iOS. xvi Core Data for iOS

. Chapter 11: Optimizing for iOS Performance and Memory Requirements This chapter is all about performance, optimization, and speed. You’ll learn some simple tricks to help your application run faster and be more responsive for the user without consuming all available memory or running down the battery. This chapter assumes you already understand about retain counts and when objects are deallocated, which affects your memory usage but which are not directly related to Core Data. . Chapter 12: Troubleshooting Core Data When things go amiss with Core Data the symptoms and error can seem obscure, even if you’ve been using it for a while. You can’t very well fix your code if you don’t understand what’s wrong. In this chapter, you’ll look at ways to help you diagnose and fix some of the most common Core Data prob- lems. Keep in mind that Core Data can be affected by problems that are not specific to Core Data; for example, memory management errors can affect any Cocoa object, and managed objects are no exception. This chapter focuses on problems specifically related to Core Data. Although the book is designed to be read in order, each chapter is mostly self-contained, so feel free to skip around to learn about specific topics. Some of the example projects in each chapter require code from a previous chapter as a starting point; if you need to a ready-made project from an earlier chapter, the sample code for the book is available online.

About the Sample Code and Coding Style

All of the source code necessary to run the examples in this book is provided inline within chapters; in order to fit within the confines of a page, the code may have rather more newline characters than you might expect. Because of the nature of the subject, the code includes a large number of accessor methods. As this book is likely to be read both by developers who prefer using full acces- sor methods and lots of nested square brackets, as well as those who have embraced Objective-C 2.0 dot syntax, we felt it important to include examples demonstrating both styles. The included code therefore uses a mixture of both traditional method calls and dot notation throughout the example listings. Feel free to substitute according to your own coding preferences. The complete source code for the projects in this book is available as a downloadable disk image (.dmg), which you can get by clicking on the Resources tab on the book’s catalog page: http://www.informit.com/title/9780321670427 The disk image contains a README file along with folders containing the projects for each chapter. Apple shipped Xcode 4 (with substantial changes over Xcode 3) just before this book went Preface xvii

to press. The screenshots in the book are taken from Xcode 4, but if you’re still using Xcode 3, it should be relatively straightforward to work out any differences. We’ve added Xcode 3-specific instructions in the text anywhere that there might be confusion over major differences. Although Mac OS X Lion had been announced, it hadn’t yet shipped publicly when this book was published, so the screenshots are taken from Mac OS X Snow Leopard, which is the current required environment for iOS (i.e., iPhone, iPad, and iPod touch) develop- ment. For Core Data development for iOS, you don’t need anything else: all the libraries, headers, and documentation are included with the Xcode tools and the iOS SDK.

Acknowledgments from Tim Isted

Although writing a book notoriously takes longer than expected, I’ve certainly pushed the boundaries on this one. I have a vivid memory of the moment the words “Core Data” appeared on a slide at Apple’s announcement of iPhone SDK 3.0. Half an hour later, Chuck and I were discussing the outline for a book dedicated to Core Data on iPhone. That was back in June 2009. Since then, the iPhone OS has become iOS, the iPad was released, iPhone 4 appeared, multitasking was introduced, Xcode 4 went public, and the goal posts kept moving. It’s hard to pick a time to publish a book on something that changes so frequently, but putting overall iOS changes aside, the Core Data framework (and certainly its API) has remained fairly stable, probably due to its earlier existence on the Mac. This book would never have made it were it not for the wonderfully patient and encouraging editorial guid- ance Chuck Toporek has given me, not to mention his personal friendship. Together we hope we’ve ensured it should remain useful across the inevitable series of major iOS version releases that will occur the moment the book hits the shelves. After a few lengthy pauses for me to deal with various nasty bouts of illness among my close family, Tom Harrington agreed to come on board to help get the book out before iOS became obsolete. His work specifically on the two performance chapters, together with his contributions across the whole book, has taken it up so many notches. The four anonymous (for the most part) technical reviewers have been fantastic. It’s all too easy to become blinkered as an Indie developer and I thank the reviewers for saving me from too many of those “I’ve always done it like this” moments. Finally, I can never thank enough the friends I have throughout the Mac/iOS developer community. It’s a wonderful team to be a part of. xviii Core Data for iOS

Acknowledgments from Tom Harrington

I’d like to thank my wife Carey for encouraging me to embark on a career that appealed to me but seemed too risky to jump into. After the dot-com boom in 2001, Carey was the one who suggested there might be more interesting things to do than look for another day job. I never expected to run my own business and would not have done so without Carey’s help. I’ve been independent ever since and have never looked back. I’d also like to thank Tim Isted and Chuck Toporek for giving me the opportunity to work on this book, and to Marcus Zarra for introducing me to Tim in the first place. Also, this book would not have been possible without the technical reviewers who help make Tim and I look good.

About the Authors

Tim Isted Tim Isted has been writing software for computers since 1995. He also builds web applications using Rails, PHP, and .NET and has been known to develop for Windows machines too. Also a professional musician and singing teacher, he tries to divide his time fairly equally between conducting, accompanying, teaching, and writing software. Previous musings on Core Data for desktop development can be found on his blog at www.timisted.net, and he is also co-organizer of NSConference, a new Mac developer conference taking place in both Europe and the USA.

Tom Harrington

Tom Harrington switched from writing software for embedded systems and Linux to Mac OS X in 2002 when he started Atomic Bird, LLC. After six years of developing highly regarded Mac software he moved to iPhone in 2008. He develops iOS software on a contract basis for a variety of clients. Tom also organizes iOS developer events in Colorado. When not writing software he can often be found on his mountain bike. His website is www.atomicbird.com. CHAPTER 2 IN THIS CHAPTER

. Persisting Objects to Disk A Core Data Primer . The Core Data Approach . Examining the Xcode Core Data Templates

In order to get the most out of Core Data, it’s extremely important to have a firm understanding of its fundamental operations. Over the course of this chapter, you’ll learn the key terms and features of the different parts of a Core Data- based application. Before looking at the Core Data terms, though, take a moment to think about how you might work with persisted data in an application without using Core Data.

Persisting Objects to Disk

When you’re working with data to be saved in an applica- tion, you typically have collections of objects, maybe held in arrays, sets or dictionaries, which need to be archived to disk. When it comes time to save the data, you might encode or serialize those objects ready to be saved into a binary file or, for small datasets, store them in a .plist file. As an alternative to working with binary files, and before Core Data came to iOS, developers could also make direct use of SQLite, a simple and very lightweight database, avail- able on iOS devices since the early versions of iPhone OS. When writing an application that made use of large collec- tions of objects, it would make sense to store those items in a database, offering huge increases in speed when saving and fetching objects. SQLite, as its name implies, is based around the Structured Query Language, or SQL. You talk to an SQL database by issuing commands to, for example, insert or select (fetch) data. If you only need a specific object from the database, you can issue a command to fetch just that object; you 10 CHAPTER 2 A Core Data Primer

don’t need to worry about the efficiency and performance issues with loading an entire binary file from disk just to get hold of a particular object. In order to work with SQLite, however, you need to make heavy use of procedural C APIs, writing lengthy portions of code to handle data access. To save an object into a SQLite database, for example, you would need to write out a string containing an SQL INSERT statement, populate that string with the values held by the object’s instance variables, convert the string to a C-string, before finally passing it to a C function.

The Core Data Approach

Core Data, on the other hand, combines all the speed and efficiency of database storage with the object-oriented goodness of object .

Entities and Managed Objects

When you create your model objects, instead of starting out by writing the .h @interface for the class, you typically begin by modeling your entities, using the Xcode Data Modeler. An entity corresponds to one type of object, such as a Patient or Doctor object, and sets out the attributes for that entity, such as firstName and lastName. You use the data modeler to set which attributes will be persisted to disk, along with various other features such as the type of data that an attribute will hold, data validation requirements, or whether an attribute is optional or required.

When you work with actual instances of model objects, such as a specific Patient object, you’re dealing with an instance of a managed object. These objects will either be instances of the NSManagedObject class, or a custom subclass of NSManagedObject. If you don’t specify a custom subclass in the modeler, you would typically access the attributes of the object through Key Value Coding (KVC), using code like that in Listing 2.1.

LISTING 2.1 Accessing the attributes of a managed object

NSManagedObject *aPatientObject; // Assuming this has already been fetched

NSString *firstName = [aPatientObject valueForKey:@”firstName”]; NSString *lastName = [aPatientObject valueForKey:@”lastName”];

[aPatientObject setValue:@”Pain killers” forKey:@”currentMedication”]; [aPatientObject setValue:@”Headache” forKey:@”currentIllness”];

If you choose to do so, you can also provide your own subclass of NSManagedObject, to expose accessor methods and/or properties for your managed object, so you could use the code shown in Listing 2.2. You’ll look at this in more detail in Chapter 6, “Working with Managed Objects.” The Core Data Approach 11

LISTING 2.2 Using a custom subclass of NSManagedObject

Patient *aPatientObject; // Assuming this has already been fetched

NSString *firstName = [aPatientObject firstName]; NSString *lastName = aPatientObject.lastName; 2

[aPatientObject setCurrentMedication:@”Pain killers”]; aPatientObject.currentIllness = @”Headache”;

You could also still access the values of the object using valueForKey:, etc., if you wish.

Relationships

The Data Modeler is also the place where you define the relationships between your enti- ties. As an example, a Patient object would have a relationship to a Doctor, and the Doctor would have a relationship to the Patient, as shown in Figure 2.1.

FIGURE 2.1 A Patient-Doctor relationship

When modeling relationships, you typically think in relational database terms, such as one-to-one, one-to-many, and many-to-many. In the example shown in Figure 2.1, a patient has only one doctor, but a doctor has many patients, so the doctor-patient relationship is one-to-many. If the doctor-patient relationship is one-to-many, the inverse relationship (patient-doctor) is obviously many-to-one. When you model these relationships in the Data Modeler, you need to model them both, explicitly, and set one as the inverse of the other. By setting the inverse relationship explicitly, Core Data ensures the integrity of your data is automati- cally maintained; if you set a patient to have a particular doctor, the patient will also be added to the doctor’s list of patients without you having to do it yourself. 12 CHAPTER 2 A Core Data Primer

You specify a name for each relationship, so that they are exposed in a similar way to an entity’s attributes. Again, you can either work with KVC methods, or provide your own accessors and property declarations in a custom subclass, using code like that in Listing 2.3.

LISTING 2.3 Working with relationships

Patient *aPatientObject; // Assuming this has already been fetched Doctor *aDoctorObject = [aPatientObject valueForKey:@”doctor”];

Patient *anotherPatientObject; // also already fetched anotherPatientObject.doctor = aDoctorObject; // The inverse relationship is automatically set too

NSLog(@”Doctor’s patients = %@”, [aDoctorObject patients]); /* Outputs: Doctor’s patients = ( aPatientObject, anotherPatientObject, etc... ) */

It’s important to note that Core Data doesn’t maintain any order in collections of objects, including to-many relationships. You’ll see later in the book how objects probably won’t be returned to you in the order in which you input them. If order is important, you’ll need to keep track of it yourself, perhaps using an ascending numerical index property for each object. If you’re used to working with databases such as MySQL, PostgreSQL, or MS SQL Server (maybe with web-based applications in Ruby/Rails, PHP, ASP.NET, etc.), you’re probably used to every record in the database having a unique id of some sort. When you work with Core Data, you don’t need to model any kind of unique identifier, nor do you have to deal with join tables between related records. Core Data handles this in the background; all you have to do is to define the relationships between objects, and the framework will decide how best to generate the underlying mechanisms, behind the scenes.

Managed Object Contexts

So far, the code in this chapter has assumed that you’ve fetched an object “from some- where.” When you’re working with managed objects and Core Data, you’re working within a certain context, known as the Managed Object Context. This context keeps track of the persistent storage of your data on disk (which on iOS is probably a SQLite store) and acts as a kind of container for the objects that you work with. The Core Data Approach 13

Conceptually, it’s a bit like working with a document object in a desktop application—the document represents the data stored on disk. It loads the data from disk when a document is opened, perhaps allowing you to display the contents in a window on screen. It keeps track of changes to the document, likely holding them in memory, and is then responsible for writing those changes to disk when it’s time to save the data.

The Managed Object Context (MOC) works in a similar way. It is responsible for fetching 2 the data from the store when needed, keeping track of the changes made to objects in memory, and then writing those changes back to disk when told to save. Unless you specifically tell the MOC to save, any changes you make to any managed objects in that context will be temporary, and won’t affect the underlying data on disk. Unlike a normal document object, however, you are able to work with more than one managed object context at a time, even though they all relate to the same underlying data. You might, for example, load the same patient object into two different contexts, and make changes to the patient in one of the contexts (as shown in Figure 2.2). The object in the other context would be unaffected by these changes, unless you chose to save the first context. At that point, a notification would be sent to inform you that another context had changed the data, and you could reload the second context if you wanted to.

FIGURE 2.2 Managed Object Contexts and their Managed Objects

Although it’s less common to work with multiple contexts on iOS than it is on the desktop, you typically use a separate context if you’re working with objects in the back- ground, such as pulling information from an online source and saving it into your local app’s data. If you choose to use the automatic Undo handling offered by managed object contexts, you might set up a second context to work with an individual object, handling undo for any changes to individual attributes as separate actions. When it was time to save that object back into your primary context, the act of saving all those changes would count as one undo action in the primary context, allowing the user to undo all the changes in one go if they wanted to. You’ll see examples of this in later chapters. 14 CHAPTER 2 A Core Data Primer

Fetching Objects

The managed object context is also the medium through which you fetch objects from disk, using NSFetchRequest objects. A fetch request has at minimum the name of an entity; if you wanted to fetch all the patient records from the persistent store, you would create a fetch request object, specify the Patient entity to be retrieved, and tell the MOC to execute that fetch request. The MOC returns the results back to you as an array. Again, it’s important to note that the order in that array probably won’t be the same as the order in which you stored the objects, or the same as the next time you execute the fetch request, unless you request the results to be sorted in a particular order. To fetch specific objects, or objects that match certain criteria, you can specify a fetch pred- icate; to sort the results in a certain order, you can provide an array of sort descriptors. You might choose to fetch all the patient records for a particular doctor, sorting them by last name. Or, if you had previously stored a numerical index on each patient as they were stored, you could ask for the results to be sorted by that index so that they would be returned to you in the same order each time.

Faulting and Uniquing

Core Data also works hard to optimize performance and keep memory usage to a minimum, using a technique called faulting.

Consider what could happen if you loaded a Patient record into memory; in order that you have access to that patient’s Doctor object, it might seem that you’d want to have the Doctor object loaded as well. And, since you might need to access the other patients related to that doctor, you should probably load all those Patient objects too. With this behavior, what you thought was a single-object fetch could turn into a fetch of thousands of objects—every related object would need to be fetched, possibly resulting in fetching your entire dataset. To solve this problem, Core Data doesn’t fetch all the relationships on an object. It simply returns you the managed object that you asked for, with the relationships set to faults. If you try and access one of those relationships, such as asking for the name of the patient’s doctor, the “fault will fire” and Core Data will fetch the requested object for you. And, as before, the relationships on a newly fetched doctor object will also be set to faults, ready to fire when you need to access any of the related objects. All of this happens automati- cally, without you needing to worry about it. A managed object context will also ensure that if an object has already been loaded, it will always return the existing instance in any subsequent fetches. Consider the code in Listing 2.4.

LISTING 2.4 Fetching unique objects

Patient *firstPatient; // From one fetch request Doctor *firstPatientsDoctor = firstPatient.doctor; Examining the Xcode Core Data Templates 15

Patient *secondPatient; // From a second fetch request Doctor *secondPatientsDoctor = secondPatient.doctor;

/* If the two patients share the same doctor, then the doctor instance returned after each fault fires will be the same instance: */ if( firstPatientsDoctor == secondPatientsDoctor ) 2 { NSLog(@”Patients share a doctor!”); }

This is known as uniquing—you will only ever be given one object instance in any managed object context for, say, a particular Patient.

Persistent Stores and Persistent Store Coordinators

The underlying data is held on disk in a persistent store. On an iOS device, this is usually a SQLite store. You can also choose to use a binary store or even your own custom atomic store type, but these require the entire object graph to be loaded into memory, which can quickly become a problem on a device with limited resources. You never need to communicate directly with a persistent store, or worry about how it is storing data. Instead, you rely on the relationship between the managed object context and a persistent store coordinator. The persistent store coordinator acts as a mediator to the managed object contexts; it’s also possible to have a coordinator talk to multiple persistent stores on disk, meaning that the coordinator would expose the union of those stores to be accessed by the managed object contexts. You won’t typically need to worry too much about persistent stores and coordinators unless you want to work with multiple stores or define your own store type. In the next section, you’ll see the code from the Xcode template project that sets up the persistent store for you. Once this is dealt with, you’ll spend most of your time concentrating on the managed objects, held within managed object contexts.

Examining the Xcode Core Data Templates

Now that you have a better idea of Core Data terminology, let’s take a look inside a standard Core Data template project for an iOS application to see how all of this works in practice. 16 CHAPTER 2 A Core Data Primer

The Navigation-Based Project Template

The Xcode project templates for the Navigation-based, Split View-based, Utility and Window-based applications all offer the option to Use Core Data, as shown in Figure 2.3.

FIGURE 2.3 The New Project Window

To follow the rest of this chapter, launch Xcode and choose File > New > New Project (Shift-„-N), then select the Navigation-based Application template. Call the project TemplateProject, and tick the Use Core Data checkbox. When the project window appears, you’ll see that there are some extra items compared to a standard project. First, the project links to the CoreData.framework. Second, there is an item called TemplateProject.xcdatamodeld. This defines the structure of your data model, which you build visually using the Xcode Data Modeler. Click on the file to open it. There are two ways to view a data model in Xcode 4—as a Table or a Graph, as shown in Figure 2.4.

NOTE Xcode 3 has only one editor mode, which combines the Table and Graph into a single view.

The Data Modeler

At the top-left of the editor, you’ll see a list of Entities. In the template file, there is a single entity, called Event. If you select this entity for display using the Table editor style, you’ll see a list of the entity’s attributes, relationships and fetched properties. Examining the Xcode Core Data Templates 17 2

FIGURE 2.4 The two Editor Styles in the Xcode 4 Data Modeler

The Event entity has a single attribute listed, called timeStamp. If you click this attribute to select it, and look in Xcode 4’s Data Model Inspector (Option-„-3), you’ll see that its Type is set to Date. This inspector offers a number of other options relating to that attribute. For example, this is where you can choose to validate the data that is stored, or mark an attribute as being optional; these options are covered in Chapter 3, “Modeling Your Data.” Xcode 4’s Graph editor style offers a visual representation of the entities in your object model. At present, there is only a single entity in the model, but if there were more than one, you would see the relationships between the entities represented by lines and arrows connecting the two, as in Figure 2.5.

Setting up the Core Data Stack

When working with data held in a persistent store, you will need to have built up a stack of objects; at the bottom is the actual persistent store on disk, then comes a persistent store controller to liaise between the store and the next level, the managed object context, as shown in Figure 2.6. It’s also possible to have more than one persistent store under the one coordinator, as well as multiple managed object contexts (as discussed earlier in the chapter). 18 CHAPTER 2 A Core Data Primer

FIGURE 2.5 Relationships between objects in the Object Graph

Managed Object Managed Object Managed Object Managed Object NSManagedObject NSManagedObject NSManagedObject NSManagedObject

Managed Object Context Managed Object Context NSManagedObjectContext NSManagedObjectContext

Persistent Store Coordinator NSPersistentStoreCoordinator (uses a managed object model)

Persistent Store Persistent Store NSPersistentStore NSPersistentStore

FIGURE 2.6 The Core Data Stack

Let’s examine the template code provided to set up this Core Data stack. Open the TemplateProjectAppDelegate.h interface file, and you’ll find that there are a number of property declarations defined for the app delegate, as shown in Listing 2.5 (the Xcode 4 templates make use of the modern runtime feature of synthesizing the corresponding instance variables). Examining the Xcode Core Data Templates 19

LISTING 2.5 The app delegate interface

@interface TemplateProjectAppDelegate : NSObject {

}

@property (nonatomic, retain) IBOutlet UIWindow *window; 2

@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext; - (NSURL *)applicationDocumentsDirectory;

@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@end

The app delegate keeps track of the managed object model, which is the information contained within the TemplateProject.xcdatamodeld file. It also has a reference to a persistent store coordinator, along with a managed object context. The applicationDocumentsDirectory is used to determine where the data will be held on disk.

Switch to the TemplateProjectAppDelegate.m interface file and scroll through the various methods that are provided. Near the bottom, you’ll find the applicationDocumentsDirectory method. As the name implies, it simply returns the path to the application’s documents directory.

Next find the persistentStoreCoordinator method. This method sets up a persistent store coordinator, to access a SQLite store file called TemplateProject., located in the application’s documents directory. The persistent store is initialized using the model provided by the managedObjectModel method, so jump to this method next.

The managedObjectModel method returns an NSManagedObjectModel object created from a file called TemplateProject.momd. When you compile the project, the TemplateProject.xcdatamodeld data model is compiled into this .momd resource and stored in the application’s .

It’s also possible to create an NSManagedObjectModel by merging all the available model files using the class method mergedModelFromBundles:, or by merging selected models using modelByMergingModels:. Although there is only a single model file (it’s actually a model bundle) in this template application, it is possible to split your model into multiple .xcdatamodeld files, if you wish. 20 CHAPTER 2 A Core Data Primer

At the top of the stack, you’ll find the managedObjectContext method. This method sets up the context using the persistent store coordinator. If you look in the awakeFromNib method, towards the top of the file, you’ll find that it sets a property on the RootViewController for a managedObjectContext. It is at this point that the chain is triggered to set up the managed object model, persistent store coordinator and finally the context.

NOTE In earlier versions of Xcode, the template code may be slightly different; for example, setting up the managed object model by merging the models in the main bundle, and setting the RootViewController’s managedObjectContext property from within application:didFinishLaunching:.

Lastly, the applicationWillTerminate: method calls a saveContext method, which checks to see whether any changes have been made to objects in the managed object context, and tries to save those changes if so. This means that the persistent store will be updated with changes from the context when the application exits. Some versions of the project template also call saveContext from applicationDidEnterBackground:, so that the store will be updated if the user switches to a different application under iOS 4 multitasking. You probably won’t need to modify the code in these methods unless you need to work with multiple stores or custom store types. Once the managed object context has been set up, it’s passed to the root view controller. This view controller has the code that actually performs the relevant fetches to display the data in a table view, and it’s this sort of code that you will typically be writing most of the time when you’re working with Core Data. In Chapter 4, “Basic Storing and Fetching,” you’ll start writing your own code to populate a table view with information from a Core Data store. Running the Application

To see the functionality you get from the basic project template, build and run the appli- cation. You’ll find that you can add to a list of Events; the table view shows these, outputting the values of the events’ timeStamp attributes. Note that you can remove items from the table view using the Edit button, or by swiping your finger across a row. A Quick Look at the RootViewController Code

To get an idea of how this all works, open up the RootViewController.m implementation file. The template application makes use of a Fetched Results Controller to simplify working with fetched objects and table views. This object is created lazily and told to fetch when it’s needed by one of the table view data source methods.

NOTE In earlier versions of Xcode, the template file creates the FetchedResultsController and executes a fetch at the end of the view controller’s viewDidLoad method. Examining the Xcode Core Data Templates 21 2

FIGURE 2.7 The Template Application in the Simulator

If you look at the code that generates the fetchedResultsController lazily, you’ll see that it’s set to use the Event entity and given sort descriptors to sort by the timeStamp attribute. The methods to display the contents in the table view are the standard table view data source methods; for the numberOfSections... and numberOfRows... methods, the template code just queries the fetched results controller object. To display the information in the cellForRowAtIndexPath: method, a configureCell:atIndexPath: method is used. Notice how simple it is to get hold of the managed object at the selected index. The code to display the time stamp is shown in Listing 2.6.

LISTING 2.6 Displaying the timestamp in the cell

NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath]; cell.textLabel.text = [[managedObject valueForKey:@”timeStamp”] description];

The fetched results controller returns the object at the specified index, and the code just queries that returned object for the description of its timeStamp key.

The commitEditingStyle:forRowAtIndexPath: method simply tells the managed object context to delete the object at the specified index path, and then asks the context to save. 22 CHAPTER 2 A Core Data Primer

This will mean that the object deleted from the table view will also be deleted from the persistent store.

Lastly, find the insertNewObject method that gets called when the user tries to add an object to the table view, and you’ll see that the procedure is:

. Get a pointer to a managed object context. . Decide which entity you need to use to create a new object. . Insert a new object for that entity, into the managed object context. . Set the relevant values on the new object. . Tell the context to save.

When the context saves, the new object is written to the persistent store. It’s as simple as that! Note that the template files are deliberately verbose—it’s common to accomplish the above using only two or three lines of code.

Summary Now that you have an idea of how a Core Data application is constructed, it’s time to start learning how to use the individual parts of the Core Data framework. In the next chapter, you’ll see best practices for constructing managed object models from the point of view of memory and performance considerations. Although the Apple-provided template application makes use of a fetched results controller, it’s a good idea to see how objects are fetched manually. Chapter 4, “Basic Storing and Fetching,” demonstrates how to work directly with managed object contexts and fetch requests to display objects in a table view. Chapter 5, “Using NSFetchedResultsController,” then shows how to take advantage of the memory optimiza- tion and performance benefits offered by the fetch results controller. Index

SYMBOLS support to managed object contexts, 176 transient eyeColor property declarations, ” (quotation marks), substituting without 108 strings, 119 addNewPerson method, 183 #ifdef directive, 218 addNewRandomDate method, 50, 58, 75 = (equality) operators, 124 allocating @dynamic keyword, 58, 91 memory. See memory @end keyword, 107 objects, 114 AND operator, 128 A APIs (application programming interfaces), 10 Abstract checkbox, 31 application:didFinishLaunchingWithOptions: abstract entity models, 189 method, 174 AbstractItem entity, 232 application programming interfaces. See APIs abstract sub-entity models, 189-190 (application programming interfaces) accessing applications, 3 managed objects, 10 Associated Press, 7 relational database systems, 3 Calcuccino, 7 accessor methods contact-management, 27 customizing, 91-93 data models, 188-192 lazy, 109 delegates, 254 non-transient properties, 109 iPhone screens, 26 troubleshooting, 266-267 MoneyWell case study, 6-7 actions, deleting undo, 181 Note Collector, 187-188 Add Attribute button, 31 AbstractItem entity, 232 add button (+), 227 BLOBs (Binary Large OBjects), 239 Add button, viewing, 50 configuring RootViewController, 192-195 Add (+) button (Xcode), 31 data models, 188-192 Add Entity button, 29 editing notes, 210-217 adding naming items, 202-210 attributes, 148, 242 SQLite debug level 1, 228 AWPerson interfaces, 106-108 supplying pre-populated data stores, convenience methods, 94 217-219 delegate methods, 77 viewing collection contents, 195-202 editor controllers, 182-183 Random Dates, 47-48 entities, 148 NSFetchedResultsController, 73-85 frameworks, 256 section index titles, 82 ImageFilename property, 242 table views, 80 objects, 96 Random People outlets to view controllers, 164 adding Search Display Controllers, persistent stores, 146 130-141 PrimitiveAccessors categories, 110 configuring, 93-98 properties, 166, 196 creating, 88-89 RandomDate objects, 50 customizing migration, 151 relationships to entities, 35-37 editing managed objects, 163-173 Search Bars, 139-141 managed object subclass files, 88 Search Display Controllers, 130-141 troubleshooting, 105 SQLDebug arguments, 227 undo support, 174-175 272 applications

running, 20 Attributes Inspector, 212 Template, 21 auto-generated AWPerson class interface, 89 testing, 135 automaticallyNotifiesObserversForKey: method, applicationWillTerminate: method, 20 91 applying automatic grouping functionality, 68 Boolean attributes, 90 automatic undo support, 174 Data Modelers (Xcode), 10, 28-37 AWAbstractItem entity, 195 managed objects, 87 AWAbstractItem.h file, 191 NSFetchedResultsController, 61 awakeFromFetch method, 115 predicates, 117 awakeFromInsert method, 115 relationships, 12 awakeFromSnapshotEvents: method, 115 sort descriptors, 45 AWCollectionViewController, 196 table views, 46-54 AWNoteEditorViewController, 211 transformable attributes, 113-114 AWNoteEditorViewController.h file, 211 transient attributes, 105-113 AWNote.h file, 191 UIColor properties, 111-113 AWPersonEditorViewController, 176, 182 archives, 9 AWPerson interfaces, adding, 106-108 arguments, 226 AWStringEditorVCDelegate protocol, 203 SQLDebug, configuring, 228 AWStringEditorViewController class, 203 validation methods, 100 AWStringEditorViewController.h file, 203 XCode, 228 Arguments Passed On Launch section, 227 B arrays, 9, 128 background colors, 112 arrows, relationships, 36 batches assigning attributes, 42 faulting, 237 Associated Press application, 7 fetching, 62 atomic binary data stores, 224 rows, loading, 62 attaching instruments, 246 behavior Attribute Inspector, 204 migration, customizing, 156 attributes overriding, 80 adding, 148, 242 RootViewController class, 49-51 assigning, 42 binary data storage, 27-28, 225 Boolean, applying, 90 binary files, 9 configuring, 42 Binary Large OBjects. See BLOBs custom managed object subclasses, 55 Bindings, 5 data, 27 bitwise operators, predicates, 123 Data Modelers (Xcode), 32 blank documents, 29 Decimal, 34 BLOBs (Binary Large OBjects) eyeColorData, 107 entities, 239-242 fullName, 107 external files, 242-244 Integer16, 34 management, 238-244 managed objects, accessing, 10 migration, 244 naming, 33 Boolean attributes, applying, 90 optional, 32 bundles, xcdatamodeld, 146 orderDate, 33 persistent, 92 C renaming, 148-152 caching, 63 String, 35 NSFetchedResultsController, 72 testAttribute, 144 objects, 234 transformable, 34, 113-114 specifying, 84 Transient, 32 Calcuccino, 7 transient, applying, 105-113 canBecomeFirstResponder method, 174 types, 34 Cancel button, 205 yearOfBirth, 156 canceling edited strings, 207 controllers 273

cancelPerson: method, 171 compound predicates, 126-129 cascading objects, 46 conditions, specifying predicates, 126 case studies configureCell:atIndexPath: method, 21, 97 Associated Press application, 7 configuring Calcuccino, 7 attributes, 42 MoneyWell for iPhone, 6-7 controls, 213 categories, adding PrimitiveAccessors, 110 currentPerson property, 165 cellForRowAtIndexPath: method, 21 custom classes for managed objects, 56-59 modifying, 59 Delete Rule, 36 cells fetching backgrounds, formatting colors, 112 limits, 230-231 contents, viewing, 193 predicates, 132-135 index paths, returning, 66 Fetch Predicates, 44 timestamps, viewing, 21 items, naming, 202-210 C language, APIs (application programming managed object values, 168 interfaces), 10 Random People application, 93-98 classes RootViewController, 192-195 AWStringEditorViewController, 203 SQLDebug arguments, 228 customizing, 56-59 , 17-20 factory methods, 55 strings, first responders, 206 files, creating, 190-192 undo managers, 180 managed objects conflicts, handling, 260-264 implementation, 90-93 connections, Search Display Controllers, 132 interfaces, 89-90 consoles, Xcode, 252 not found errors, 255-256 contact-management applications, 27 NSCompoundPredicate, 128 contents NSEntityDescription, 42 cells, viewing, 193 NSFetchedResultsController, 6 collections, viewing, 195-202 NSManagedObject, 11 contexts NSObject, 23 editing, 180 NSPredicate, 118, 126, 231 managed objects RandomDate, 58 editing, 177 RootViewController, 49-51 resetting, 181-182 specifying, 30 MOC (Managed Object Context), 12-13 subclasses, customizing, 11 multiple managed object, 175-183 clearing fetch predicates, 135-136 objects, modifying, 69-72 code, RootViewController, 21-22 saving, 42-43 collections, 9 contextual menus for attributes (Xcode), 106 contents, viewing, 195-202 controllers items, placing inside, 199 editors, adding objects, 182-183 tracking, 196 fetched results, 6, 68, 192 view controllers, initializing, 198 main view, loading, 254 collisions, threading, 260-264 NSFetchedResultsController, 62. See also colors, 111 NSFetchedResultsController backgrounds, 112 RootViewController code, 21-22 commands Search Display Controllers, adding, 130-141 Copy (Xcode), 106 views Paste (Xcode), 106 adding outlets to, 164 commitEditingStyle:forRowAtIndexPath: creating, 203-210 method, 22 generating, 166 comparing strings, 124-126 initializing, 176, 198 comparison operators, predicates, 122-123 multiple, 163 viewing, 167

How can we make this index more useful? Email us at [email protected] 274 controls, configuring

controls, configuring, 213 defining convenience methods, adding, 94 entities, 35 convention, adding, 152 relationships, 4 converting objects, 237-238 store types, 15 coordinators, persistent stores, 15 delegates Copy command (Xcode), 106 applications, 254 copying pre-populated data stores, 218 methods Core Data, when not to use, 248 adding, 77 crashes, 43, 252, 265-266. See also writing, 95 troubleshooting deleteCacheWithName: method, 72 creating. See formatting deleteObject: method, 45 currentPerson property, 165 Delete Rule, 36 customizing deleting accessor methods, 91-93 managed objects, 45-46 classes, 56-59 objects, 76 entities, 156-160 RandomDate objects, 53 migration, 151 undo actions, 181 order of section of index titles, 82 validation prior to, 104 sections, returning index titles, 81 denying objects, 46 subclasses, 11 design, data models, 24-28 custom managed object subclasses desktops, differences between Core Data iOS attributes, 55 and, 5-6 interfaces, 55 Destination drop-down box, 36 detail disclosure indicators, 167 D Detection options, 212 databases, 10 devices, overview of, 3 normalization, 25 dictionaries relational database systems, 3 sets of, 9 SQL (Structured Query Language), 4 troubleshooting, 129 storage, 10 DidChangeContent method, 69 data conflicts, handling, 260-264 didChangeObject method, 78 Data Modeler (Xcode), 10, 16-18 directives, #ifdef, 218 applying, 28-37 directories, Documents, 149 describing entities, 23-24 disks, persisting objects to, 9-10 fetch requests, editing, 121 displaying. See viewing relationships, 11-12 dividing data into entities, 24-28 Data Model Inspector (Xcode), 30, 149 documents, blank, 29 data models, applications, 188-192 Documents directory, 149 data normalization, 25-26 Done button, 205 data source methods, 64-72 data stores, types, 224-230 E data validation. See validation Edit button, 54 dateFilterPredicate method, 140 editing datePickerValueDidChange: method, 180 contexts, 180 dates enabling, 215 filters, 140 fetch requests, 121 validation, 100 items, naming, 202-210 debugging, 226. See also troubleshooting managed objects, 163-173, 177 Decimal attribute, 34 notes, 210-217 declaring relationships, 107 preventing, 136 decreased property, 92 strings, saving, 207 Default text field, 33 files 275 editingContext property, 176 F editors controllers, adding objects, 182-183 factory method classes, 55 Graph, 17, 31, 106 faulting, 14-15 mapping models, 154 batches, 237 notes, interfaces, 211 management, 235-238 Table, 31 objects, re-faulting, 237-238 Edit Scheme window, 226 troubleshooting, 268-269 efficiency of databases, 10 fetchedResultsController lazy accessor, 134 enabling fetched results controllers, 6 debugging, 226 fetching, 41 editing, 215 batches, 62 lightweight migration, 146-148 data, 10 Enterprise Objects Framework. See EOF limits, configuring, 230-231 Entities, 16 managed objects, saving, 44-45 entities NSFetchedResultsController, 61 abstract, models, 189 objects, 14 AbstractItem, 232 persistent stores, 118 adding, 148 troubleshooting, 269-270 AWAbstractItem, 195 optimizing, 230-235 BLOBs (Binary Large OBjects), 239-242 predicates creating, 29-31, 34 clearing, 135-136 customizing, 156-160 configuring, 132-135 dividing data into, 24-28 properties, 31, 113 Event, 145 RandomDate objects, 51-52 managed objects and, 10-11, 23-24 requests modifying, 149 editing, 121 renaming, 148-152 executing, 44, 63, 122 Entity Inspector, 31, 56 formatting, 44 Entity list, 29 monitoring, 247 Entity Mappings list, 156 predicates, 117. See also predicates environment variables, 226 storing, 120 EOF (Enterprise Objects Framework), 3 results, 75, 192 equality (=) operators, 124 sorting, 113 errors, 43 fetchLimit property, 230 executeFetchRequest:error:, 45 Fetch Predicates, configuring, 44 migration, 143-145 fetchRandomDates method, 73 troubleshooting, 251-256. See also fields, text, 214 troubleshooting files validation, 103 AWAbstractItem.h, 191 evaluating statements, 117. See also AWNoteEditorViewController.h, 211 predicates AWNote.h, 191 Event entities, 145 AWStringEditorViewController.h, 203 Executables section, 228 binary, 9 executeFetchRequest:error:, 45 BLOBs (Binary Large OBjects), 242-244 executing fetch requests, 44, 63, 122 classes, creating, 190-192 expressions, NSPredicate class, 126 LightweightMigrationTestAppDelegate.m, Extensible Markup Language. See XML 146 external files, BLOBs (Binary Large OBjects), Managed Object Class, 57 242-244 managed objects, subclasses, 87-93 eyeColorData attribute, 107 MigrationTest.xcdatamodeld, 144

How can we make this index more useful? Email us at [email protected] 276 files

raw data, viewing, 200-202 Handling Underlying Data Changes section, 63 RootViewController.h, 166 headers support, searching, 149 files, importing model class files, 192 filters sections, 68 dates, 140 hiding keyboards, 166 Search Bars, adding, 139-141 history of Core Data, 3-4 first responders strings, 206 I view controllers, 174 identifiers, renaming, 150 for loops, compound predicates, 128 IDs, managed objects, 264 Format Specifiers section, 118 ImageFilename property, adding, 242 format strings, creating predicates, 118-120 implementation formatting accessor methods, customizing, 91-93 custom classes for managed objects, 56-59 AWPerson interfaces, adding, 106-108 entities, 29-31, 34 classes, managed objects, 90-93 items, 194 data source methods, 75 managed objects, 41-43 getter methods, 92 NSFetchedResultsController, 62-64 setter methods, 91 objects, 10, 43 importing model class files, 192 predicates, 118-120 Indexed checkbox, 32 properties, 31-35 indexes Random People application, 88-89 paths, returning cells, 66 relationships, 35-37 titles, 68, 79, 81 stacks, 17-20 infinite loops, 101 subclasses, 54-59 inheritance, NSEntityMigrationPolicy, 156 view controllers, 203-210 initializing frameworks, 3 managed objects, troubleshooting, 265-266 adding, 256 non-persistent properties, 114-116 EOF (Enterprise Objects Framework), 3 stacks, 253 freeing up memory, 224 view controllers, 176, 198 fullName attribute, 107 init method, 178 fullName property, 93 in-memory data stores, 224 functionality, 4, 25 IN operator, 129 automatic grouping, 68 insertNewObject method, 22, 193 of Core Data, 4 instances, variables, 73 Note Collector application, 210. See also instantiation, fetched results controller sub- Note Collector application classes, 81 undo, 163 instruments, monitoring with, 245-248 validation, 98 Integer16 attribute, 34 , 5, 213 G Interface Editor, 5 generating view controllers, 166 interfaces getter methods APIs (application programming interfaces), implementation, 92 10. See also APIs transient properties, adding, 108 AWPerson, adding, 106-108 Graph editor, 17, 31, 106 classes, managed objects, 89-90 custom managed object subclasses, 55 H note editors, 211 handling updating, 165 data conflicts, 260-264 Inverse drop-down box, 36 tap on accessory buttons, 206 inverse relationships, 4, 11, 36 managers, configuring undo 277

iOS Managed Object Class file, 57 optimizing, 223 Managed Object Context. See MOC (Managed use of Core Data on, 4-5 Object Context) iPhones managedObjectContext method, 20 application screens, 26 managedObjectContext property, passing, 49 MoneyWell case study, 6-7 managedObjectModel method, 19 OS 3.0, table views, 67 managed objects itemName property, 193 accessing, 10 items applying, 87 collections, placing inside, 199 attributes, configuring, 42 creating, 194 binary data storage, 27-28 naming, 202-210 classes creating files, 190-192 J implementation, 90-93 join tables, 24 interfaces, 89-90 conflicts, 263 contexts K editing, 177 keyboards, hiding, 166 resetting, 181-182 key paths, predicates, 123-124 creating, 41-43 Key-Value-Coding. See KVC and data validation, 5 Key-Value-Observing. See KVO deleting, 45-46 keywords editing, 163-173 as attribute names, 33 and entities, 23-24 @dynamic, 58, 91 entities and, 10-11 @end, 107 IDs, 264 KVC (Key-Value-Coding), 5, 10, 42, 54, 91 invalidation, 267-268 KVO (Key-Value-Observing), 5 lifecycles, 114-116 notifications, 91 MOC (Managed Object Context), 12-13 multiple contexts, 175-183 L multithreading, 257 lazy accessor methods, 109 predicates, 117. See also predicates lifecycles, managed objects, 114-116 properties, updating, 168-170 lightweight migration, 145-148 saving, fetching, 44-45 LightweightMigrationTestAppDelegate.m file, subclasses, 54-59, 87-93 146 tracking, 164-168 LIMIT parameter, 230 transformable attributes, 113-114 limits, configuring fetching, 230-231 transient attributes, 105-113 lists troubleshooting, 265-269 Entity, 29 validation, 99-105, 171-173 Entity Mappings, 156 values loading configuring, 168 main view controllers, 254 modifying, 179 properties, preventing, 237 management rows, 62 BLOBs (Binary Large OBjects), 238-244 loops contact-management applications, 27 for, compound predicates, 128 faulting, 235-238 infinite, 101 memory, 248-249 relationships, 4 M state, 5 Mac OS X 10.4 Tiger, 3 managers, configuring undo, 180 main view controllers, loading, 254

How can we make this index more useful? Email us at [email protected] 278 many-to-many relationships

many-to-many relationships, 4, 24 init, 178 mapping insertNewObject, 22, 193 models, 151-155 managedObjectContext, 20 modifying, 157 managedObjectModel, 19 object-relational, 3 NSFetchedResultsControllerDelegate, 69 PersonToPerson, 156 persistentStoreCoordinator, 19 memory predicateForSearchString:, 139, 140 BLOBs (Binary Large OBjects), 238 primitiveValueForKey:, 92 data stores, 225 refreshObject:mergeChanges:, 237 freeing up, 224 RootViewController.m, 159 management, 248-249 safe fault-free, 236-237 performance, 27 save:, 46 requirements, 223 saveContext, 20 merging changes from one context to another, savePerson:, 171 176-178 sectionIndexTitleForSectionName:, 81-82 messages setCurrentPerson:, 177, 182 crashes, 265 setRelationshipKeyPathsForPrefetching:, errors, 103, 252 234 willSave, 110 setter, adding for transient properties, methods 110-111 accessor tableView:didSelectRowAtIndexPath:, 199 customizing, 91-93 textFieldShouldEndEditing, 100 lazy, 109 textFieldShouldReturn:, 205 non-transient properties, 109 userDidSaveStringEditorVC:... callback, 209 troubleshooting, 266-267 validateValue:ForKey:error:, 102 addNewPerson, 183 viewDidLoad, 50, 74, 96, 168 addNewRandomDate, 50, 58, 75 viewWillDisappear:, 168, 181 application:didFinishLaunchingWithOptions:, WillChange, 69 174 migration, 143 applicationWillTerminate:, 20 BLOBs (Binary Large OBjects), 244 automaticallyNotifiesObserversForKey:, 91 lightweight, 145-148 awakeFromFetch, 115 models, mapping, 151-155 awakeFromInsert, 115 overview of, 143-145 awakeFromSnapshotEvents:, 115 policies, custom entities, 156-160 canBecomeFirstResponder, 174 summaries, 155 cancelPerson:, 171 MigrationTest.xcdatamodeld file, 144 cellForRowAtIndexPath:, 21, 59 MOC (Managed Object Context), 12-13 commitEditingStyle:forRowAtIndexPath:, 22 models, 3 ConfigureCell:atIndexPath:, 21 abstract entities, 189 configureCell:atIndexPath:, 97 abstract sub-entities, 189-190 convenience, adding, 94 applications, 188-192 dateFilterPredicate, 140 entities, dividing data into, 24-28 datePickerValueDidChange:, 180 mapping, 151-155 delegates modifying, 106, 144-145 adding, 77 naming, 152 writing, 95 objects, 10, 41 deleteCacheWithName:, 72 Random Dates data, 48 deleteObject:, 45 Random People application, 89 DidChangeContent, 69 relationships, 11 didChangeObject, 78 terminology, 24-25 fetchRandomDates, 73 modifying getter, adding for transient properties, 108 addNewRandomDate method, 58 objects 279

cellForRowAtIndexPath: method, 59 notes entities, 149 editing, 210-217 lightweight migration, 148 editors, interfaces, 211 managed object values, 179 not found errors, classes, 255-256 mapping, 157 notifications models, 106, 144-145 KVO (Key-Value-Observing), 91 objects, 69-72 registering, 180 persistent properties, 111 NSCompoundPredicate class, 128 predicates, searching, 136-139 NSEntityDescription class, 42 sections, 70 NSEntityMigrationPolicy MoneyWell for iPhone case study, 6-7 inheritance, 156 monitoring objects, 156 with instruments, 245-248 NSError objects, 45 SQLite data stores, 225-227 NSFetchedResultsChangeDelete, 71 multiple data model versions, 145-148 NSFetchedResultsChangeInsert, 71 multiple managed object contexts, 175-183 NSFetchedResultsChangeMove, 71 multiple search words, creating predicates for, NSFetchedResultsChangeUpdate, 71 137 NSFetchedResultsController class, 6 multiple view controllers, 163 applying, 61 multitasking, 43 caching, 72 multithreading, 257-258 creating, 62-64 data source methods, 64-72 N instances, variables, 73 naming. See also renaming overview of, 62 attributes, 33 Random Dates application, 73-85 entities, modifying, 149 sections, 235 items, 202-210 subclasses, 80-85 models, 152 NSFetchedResultsControllerDelegate methods, relationships, 36 69 RootViewController, 195 NSInferMappingModelAutomaticallyOption, 147 Navigation-based project templates (Xcode), NSManagedObject class, 11 16-17 NSManagedObject subclass, 56, 191 New File sheet, 28 NSMergeByPropertyObjectTrumpMergePolicy, New Project window, 16 262 NeXT, 3 NSMergeByPropertyStoreTrumpMergePolicy, No Action Delete Rule, 46 262 non-persistent properties, initializing, 114-116 NSMigratePersistentStoresAutomaticallyOption, 147 normalization, 25-26 NSObject class, 23 Note Collector application, 187-188 NSOverwriteMergePolicy, 262 AbstractItem entity, 232 NSPredicate class, 118, 126, 231 BLOBs (Binary Large OBjects), 239 NSRollbackMergePolicy, 263 collection contents, viewing, 195-202 nullifying objects, 46 data models, 188-192 items, naming, 202-210 notes, editing, 210-217 O pre-populated data stores, supplying, object-relational mapping, 3 217-219 objects RootViewController, configuring, 192-195 adding, 96 SQLite debug level 1, 228 allocating, 114 BLOB (Binary Large OBject) management, 238-244 caching, 234

How can we make this index more useful? Email us at [email protected] 280 objects

cascading, 46 orderDate attribute, 33 contexts, modifying, 69-72 order of section of index titles, customizing, 82 converting, 237-238 OR operator, 128 creating, 43 overriding behavior, 80 deleting, 76 denying, 46 P disk, persisting to, 9-10 parameters, LIMIT, 230 editor controllers, 182-183 Parent Entity, 30 EOF (Enterprise Objects Framework), 3 parsers, tokens, 118 fetching, 14 passing managedObjectContext properties, 49 managed. See managed objects Paste command (Xcode), 106 models, 10, 41 paths modifying, 71 indexes, returning cells, 66 NSEntityMigrationPolicy, 156 key, predicates, 123-124 nullifying, 46 performance object-relational mapping, 3 memory, 27 persistent stores, fetching, 118 monitoring, 245-248 pre-fetching, 234-235 optimizing, 224 RandomDate requirements, 223 adding, 50 persistent attributes, 92 deleting, 53 persistentStoreCoordinator method, 19 fetching, 51-52 persistent stores, 15, 43, 105. See also storage viewing, 52-53 adding, 146 re-faulting, 237-238 coordinators, 257 relationship management, 4 objects, fetching, 118 releasing, 114 persisting objects to disk, 9-10 serialization, 10 PersonToPerson mapping, 156 SQLite data stores, 225 policies, migration, 156-160 troubleshooting, 269-270 predicateForSearchString: method, 139-140 unique, fetching, 14 predicates one-to-many relationships, 4 applying, 117 one-to-one relationships, 4 bitwise operators, 123 operators comparison operators, 122-123 AND, 128 compound, 126-129 IN, 129 conditions, specifying, 126 equality (=), 124 creating, 118-120 OR, 128 fetching predicates clearing, 135-136 bitwise, 123 configuring, 132-135 comparison, 122-123 key paths, 123-124 optimizing optimizing, 231-233 fetching, 230-235 overview of, 117-124 iOS, 223 relationships, 129-130 performance, 224 searching, modifying, 136-139 predicates, 231-233 sets, 129-130 optional attributes, 32 SQL queries, 130 options strings, comparing, 124-126 Detection, 212 variables, 120-122 NSInferMappingModelAutomaticallyOption, pre-fetching. See also fetching 147 objects, 234-235 NSMigratePersistentStoresAutomatically- relationships, 233-234 Option, 147 requirements 281

pre-loading property values, 235 Random Dates application, 47-48 pre-populated data stores, supplying, 217-219 NSFetchedResultsController, 73-85 preventing section index titles, 82 editing, 136 table views, 80 property loading, 237 Random People application PrimitiveAccessors categories, adding, 110 configuring, 93-98 primitiveValueForKey: method, 92 creating, 88-89 programming RootViewController code, 21-22 managed objects project templates, 252 editing, 163-173 properties subclass files, 88 adding, 166 migration, customizing, 151 collections, tracking, 196 Search Display Controllers, adding, 130-141 creating, 31-35 troubleshooting, 105 decreased, 92 undo support, 174-175 editingContext, 176 raw data files, viewing, 200-202 fetching, 31, 113 redo, registering notifications, 180 fetchLimit, 230 reducing memory usage, 224 fullName, 93 re-faulting objects, 237-238 ImageFilename, adding, 242 referential integrity, 4 itemName, 193 Refractor tool (Xcode), 195 loading, preventing, 237 refreshObject:mergeChanges: method, 237 managed objects, updating, 168-170 registering undo/redo notifications, 180 non-persistent, initializing, 114-116 relational database systems, 3 sorting, 113 Relationship inspector, 35 specifying, 114 relationships, 25 synthesizing, 197, 204 applying, 12 testing, 129 arrows, 36 transient, 105 creating, 35-37 UIColor, applying, 111-113 Data Modelers (Xcode), 11-12 undoManager, 174 declaring, 107 validation, 99-104 management, 4 values naming, 36 pre-loading, 235 predicates, 129-130 troubleshooting, 265-266 pre-fetching, 233-234 protocols, AWStringEditorVCDelegate, 203 superCollection, 192 releasing objects, 114 Q remove button (-), 228 queries renaming fetched results, 68 attributes, 148-152 SQL predicates, 130 entities, 148-152 quotation marks (“), substituting without identifiers, 150 strings, 119 RootViewController, 195 requests R fetching editing, 121 RandomDate class, 58 executing, 44, 63, 122 RandomDate objects formatting, 44 adding, 50 monitoring, 247 deleting, 53 NSFetchedResultsController, 61 fetching, 51-52 requirements viewing, 52-53 memory, 223 performance, 223 validation, 10

How can we make this index more useful? Email us at [email protected] 282 resetting contexts, managed objects

resetting contexts, managed objects, 181-182 index titles, 81 results information about, returning, 68-69 fetched results controllers, 6 modifying, 70 fetching, 75, 192 NSFetchedResultsController, 235 NSFetchedResultsController, 61 sorting, 170 troubleshooting, 270 table views, 65-67 returning selecting cells, index paths, 66 instruments, 246 custom section index titles, 81 key paths in Xcode 3, 124 information about sections, 68-69 serialization, objects, 10 RootViewController class setCurrentPerson: method, 177, 182 behavior, 49-51 setRelationshipKeyPathsForPrefetching: Note Collector application, configuring, method, 234 192-195 sets renaming, 195 dictionaries, 9 RootViewController code, 21-22 predicates, 129-130 RootViewController.h file, 166 setter methods RootViewController.m method, 159 implementation, 91 rows transient properties, adding, 110-111 loading, 62 Simulator, 21, 252 table views, 65-67 Size Inspector, 212 rules, 41 sizes, fetching, 231 Delete Rule, 36, 46 sort descriptors, 45, 74 object validation, 5 sorting relationships, 4 fetching, 113 running applications, 20 properties, 113 sections, 170 S troubleshooting, 269-270 safe fault-free methods, 236-237 years, 159 sample applications, Note Collector, 187-188 specifying saveContext method, 20 caching, 84 save: method, 46 classes, 30 savePerson: method, 171 conditions, predicates, 126 saving entities, 24 contexts, 42-43 inverse relationships, 36 edited strings, 207 properties, 114 managed objects, fetching, 44-45 speed, optimizing, 224 objects, 43 SQL (Structured Query Language), 4, 10, 130 strings, editing, 207 SQLDebug argument, configuring, 228 screens, iPhone applications, 26 SQLite, 4, 10 Search Bars, adding, 139-141 BLOBs (Binary Large OBjects), 238 Search Display Controllers, adding, 130-141 data store, 224-227 searching stacks predicates, modifying, 136-139 formatting, 17-20 support files, 149 initializing, 253 sectional table views, 65 startup, troubleshooting, 254-255 sectionIndexTitleForSectionName: method, state management, 5 81-82 statements, predicates, 117. See also sections predicates customizing, returning index titles, 81 storage, 41 Format Specifiers, 118 binary data, 27-28 headers, 68 databases, 10 troubleshooting 283

data store types, 224-230 TemplateProjectAppDelegate.h interface file, 18 fetch requests in data models, 120 templates incompatibility, 145 NSManagedObject subclass, 56 persistent stores, 105 projects, 252 String attribute, 35 Xcode, 15-22 String Programming Guide, 118 temporary object IDs, 265 strings terminology, models, 24-25 comparing, 124-126 testAttribute attribute, 144 editing, saving, 207 testing first responders, configuring, 206 applications, 135 predicates, creating, 118-120 MigrationTest.xcdatamodeld file, 144 substituting, 119 properties, 129 Structured Query Language. See SQL text, fields, 214 subclasses. See also classes textFieldShouldEndEditing method, 100 customizing, 11 textFieldShouldReturn: method, 205 managed objects, 54-59, 87-93 threading NSFetchedResultsController, 80-85 collisions, 260-264 NSManagedObject, 191 multithreading, 257-258 UIViewController, 210 troubleshooting, 257-265 sub-entities, abstract models, 189-190 timestamps, viewing, 21 sub-predicates, 128. See also predicates titles substituting strings, 119 indexes, 68, 79, 81 substitution variables, 120-121 root view controllers, 168, 198 summaries, migration, 155 tokens, predicates, 118 superCollection relationships, 192 tools, Refractor (Xcode), 195 supplying pre-populated data stores, 217-219 tracking support changes, 13 data stores, 224-230 collections, 196 files, searching, 149 managed objects, 164-168 managed object contexts, adding, 176 versions, 151 undo, 174-175 Transformable attribute, 34 synthesizing properties, 197, 204 transformable attributes, 113-114 Transient attributes, 32 T transient attributes, applying, 105-113 Table editor, 31 triggering KVO (Key-Value-Observing) notifica- tables tions, 91 databases, 24. See also databases troubleshooting, 251 join, 24 accessor methods, 266-267 SQL (Structured Query Language), 130 dictionaries, 129 views errors, 251-256 applying, 46-54 faulting, 268-269 data source methods, 64-72 iPhone OS 3.0, table views, 67 NSFetchedResultsController, 62 managed objects, 265-269 Random Dates application, 80 migration, 143-145 rows, 65-67 not found errors, classes, 255-256 Search Display Controllers, 131 objects, fetching, 269-270 sections, 65-67 Random People application, 105 writing delegate methods, 95 results, 270 tableView:didSelectRowAtIndexPath: method, startup, 254-255 199 threading, 257-265 Template application, 21

How can we make this index more useful? Email us at [email protected] 284 types

types versioning, 143 attributes, 34 multiple data model, 145-148 data stores, 224-230 tracking, 151 instruments, 245 Versioning area, 31 viewDidLoad method, 50, 74, 96, 168 U viewing UIColor properties, applying, 111-113 Add button, 50 UIViewController subclass, 210 cells, 193 Undefined type, 34 collections, 195-202 undo iPhone applications, 26 actions, deleting, 181 note editors, 215 functionality, 163 notes, 210-217 managers, configuring, 180 RandomDate objects, 52-53 notifications, registering, 180 raw data files, 200-202 stacks, 5 timestamps, 21 support, 174-175 view controllers, 167 undoManager property, 174 views uniquing, 14-15 controllers updating adding outlets to, 164 interfaces, 165 creating, 203-210 properties, managed objects, 168-170 as first responders, 174 userDidSaveStringEditorVC:... callback method, generating, 166 209 initializing, 176, 198 User Info area, 31 multiple, 163 userInfo key, 207 viewing, 167 tables V applying, 46-54 data source methods, 64-72 validateValue:ForKey:error: method, 102 NSFetchedResultsController, 62. See validation also NSFetchedResultsController dates, 100 Random Dates application, 80 errors, 103 rows, 65-67 functionality, 98 sections, 65-67 managed objects, 99-105, 171-173 writing delegate methods, 95 managed objects and data, 5 viewWillDisappear: method, 168, 181 prior to deletion, 104 properties, 99-104 requirements, 10 W values WebObjects, 3 managed objects WillChange method, 69 configuring, 168 willSave message, 110 modifying, 179 windows properties Edit Scheme, 226 pre-loading, 235 New Project, 16 troubleshooting, 265-266 writing delegate methods, 95 validation, 100 variables X environment, 226 xcdatamodeld bundles, 146 instances, NSFetchedResultsController, 73 Xcode, 5 predicates, 120-122 Add (+) button, 31 substitution, 120 arguments, 228 Calcuccino, 7 zeros, iPhone OS 3.0, troubleshooting table views 285

consoles, 252 contextual menus for attributes, 106 Data Modeler, 10, 16-18. See also Data Modelers (Xcode) applying, 28-37 describing entities, 23-24 editing fetch requests, 121 Data Model Inspector, 30 key paths, selecting, 124 migration summaries, 155 MoneyWell, 6-7 Refractor tool, 195 templates, 15-22 XML (Extensible Markup Language), 4 Y yearOfBirth attribute, 156 years, sorting, 159 Z zeros, iPhone OS 3.0, troubleshooting table views, 67

How can we make this index more useful? Email us at [email protected]