Lập trình Wrox Professional Xcode 3 cho Mac OS part 43 pps

9 204 0
Lập trình Wrox Professional Xcode 3 cho Mac OS part 43 pps

Đang tải... (xem toàn văn)

Thông tin tài liệu

326 ❘ CHAPTER 15 DATA MODELING CREATING AN INSTANT INTERFACE Xcode can create an “ instant interface ” from a data model. An instant interface produces a functional Cocoa user interface that allows you to enter and edit data in your data model. This can be a huge time saver if you are just getting your application going or just need a minimal interface in which to view or edit your data. You often have some portion of a working data model, but no data and little or nothing that resembles an application. To create an instant interface, you ’ ll fi rst need a window to put it in: open a nib document in Interface Builder that already has a Cocoa window in it, create a new nib document, or add a new window object to an existing nib document. You can now initiate the interface builder process from either Xcode or Interface Builder: To use Xcode, arrange the window so that it is visible on the screen alongside your data model window in Xcode. Switch back to the data model window. Select the Pointer tool. While holding down the Option key, click and drag an entity from the data model diagram and drop it into the Interface Builder window. When you start the drag, a shadow of the entity with a + sign follows the cursor. If it does not, you are not dragging a copy of the entity. To use Interface Builder, drag a Core Data Entity object (you ’ ll fi nd it in the Core Data group) from the library palette into the window. A browser appears. Select the project, data model, and entity for which you want to generate the interface. Xcode now asks you if you want an interface that represents one or many entity objects. Entry fi elds are created for each attribute. For a collection of entities, Fetch, Add, and Delete buttons can be created along with a table listing all of the instances in the collection. Figure 15 - 16 shows the instant interface created for many Faculty entities. ➤ ➤ FIGURE 15-16 c15.indd 326c15.indd 326 1/21/10 3:52:18 PM1/21/10 3:52:18 PM Download at getcoolebook.com Amazingly, the entire interface is produced without any code. The interface is constructed using bindings and Interface Builder connections. If nothing else, it ’ s a testament to the power of bindings. A little time spent exploring these bindings can be very educational. MIGRATING DATA SCHEMAS The problem with persistent data is that it is, well, persistent. Data written to a data fi le might exist for years, even decades, while your application continues to evolve. Unless your data model is trivial, or you have exceptional foresight, a time will come when you need to change your data model, such that the data model of your application no longer agrees with the structure of the existing database. When this happens, your application is no longer able to read the previously written data. The important thing to remember is this: A data schema must agree with the format and organization of the information in the data store. Any discrepancies make the two inoperable. To help circumvent this inevitable disaster, Core Data supports data model versioning . Instead of simply changing your data model, you create a new one — a version. When your new application attempts to access its old data, Core Data locates the previous data schema version, uses that to read the data, and then transitions the data from the old schema to the new one; a process called data migration . Make backups of your existing (working) data stores before beginning any migration project. You probably won ’ t get it right the fi rst time, which might leave you with an incorrectly migrated data store. This section describes the data modeling tools that let you confi gure versions, defi ne mappings between versions, and provide hints for Core Data to use during migration. You should read the Core Data Model Versioning and Data Migration Programming Guide for more in - depth information, as well as the programmatic requirements. Core Data migration requires code to be added to your application; it won ’ t happen automatically, even after you ’ ve followed all of the steps in this section. See the Core Data Model Versioning and Data Migration Programming Guide for the code needed to request or initiate a data migration. ➤ Migrating Data Schemas ❘ 327 c15.indd 327c15.indd 327 1/21/10 3:52:18 PM1/21/10 3:52:18 PM Download at getcoolebook.com 328 ❘ CHAPTER 15 DATA MODELING Creating a New Version The fi rst step in any migration strategy is to create a new version of your data schema. With your current data model open, or selected in the source group, choose Design ➪ Data Model ➪ Add Model Version. A copy of the model will appear in your project, as shown in Figure 15 - 17. If this is your fi rst alternate version, your single data model document becomes a group containing the original and all subsequent versions. This parallels the organization of localized resources, which appear as a group containing their individual variants. When compiled, all of the versions will be combined into a single managed object model (mom) bundle, providing your application with run time access to all versions. One version is designated as the current version, indicated by a check mark (see Figure 15 - 17). To change the current version, open or select the desired data model document and choose Design ➪ Data Model ➪ Set Current Version. Be careful not to build your data models twice. When you create the fi rst new version of your data model, your mom document deployment changes from building a single .mom fi le to packaging multiple .mom fi les inside a nested .momd bundle. The .momd bundle is built by the data model ( .xcdatamodeld ) group that appears in your project. The data model source group should be included in the target — that group compiles all your versions and deploys a single bundle. The individual .xcdatamodel source fi les inside the group should not be included in the same target. If you include both, the application ’ s bundle will contain duplicate data models — one inside the bundle and one outside. Core Data will (by default) attempt to merge these, and your application will abort with obscure errors like “ Can ’ t merge models with two different entities named ‘ User ’ . ” You may need to perform a Build ➪ Clean to erase any stray deployments of the old model. Chapter 16 explains target membership. Each version has an arbitrary version identifi er string that you assign. Open the data model, ensure that no entities or properties are selected, and choose the File ➪ Get Info command. In the data model ’ s info window, switch to the Versioning tab and assign the model a version identifi er, as shown in Figure 15 - 18. FIGURE 15-17 FIGURE 15-18 c15.indd 328c15.indd 328 1/21/10 3:52:26 PM1/21/10 3:52:26 PM Download at getcoolebook.com Now make the needed modifi cations to the newly created data schema version. The next two sections will help you confi gure the migration from the old schema to the new one. Adding Lightweight Migration Hints If you are using Mac OS X 10.6 or later, Core Data provides a lightweight migration strategy for data models with only superfi cial changes. If you are using an earlier version of Core Data, or if you make signifi cation changes to your data model, you ’ ll need to create a mapping, as described in the next section. Lightweight migration has several advantages: You don ’ t have to create a migration mapping . You might not have to version your data model . It ’ s fast . Core Data can migrate from one schema to another as long as the changes are limited to: Adding new attributes to an entity Making a required attribute optional Making an optional attribute required and providing a default value Renaming an entity Renaming an attribute As long as your data schema changes are confi ned to this set of changes, you can use lightweight migration. Renaming an entity or attribute requires you to create a data model version and provide Core Data with a little extra assistance. In the confi gurations inspector of the entity or attribute is a Renaming Identifi er, as shown in Figure 15 - 19. ➤ ➤ ➤ ➤ ➤ ➤ ➤ ➤ FIGURE 15-19 If you need to rename an entity or attribute, fi rst create a new version of your data model. In the new version, rename the element and then set this fi eld to the element ’ s previous name. This tells Core Data which entity or attribute in the old schema corresponds to the new one. Migrating Data Schemas ❘ 329 c15.indd 329c15.indd 329 1/21/10 3:52:30 PM1/21/10 3:52:30 PM Download at getcoolebook.com 330 ❘ CHAPTER 15 DATA MODELING If you didn ’ t rename any entities or attributes, you can use lightweight migration without creating a new version of your data schema. See the Data Migration Guide for the cases where you don ’ t need to create a data schema version. Creating a Migration Mapping A migration mapping transitions the data from one schema to another. You can initiate a migration programmatically or let the Core Data framework perform it automatically, as needed. In either case, the migration proceeds in roughly the following phases: 1. The versions of the old and new data schemas are identifi ed and a suitable mapping is found. 2. The old data store is opened and a new data store is created. 3. Objects are created from the old data store. 4. The mapping is used to create new objects in the new data store, and then insert copy/ convert the old attributes into new attributes. 5. The relationships between old objects are replicated in the new objects. 6. The new objects are written to the new data store and the old objects are discarded. The Core Data framework provides many of the basic tools needed to map one data schema to another, and most of these can be confi gured in Xcode ’ s mapping model tool. If you need a more sophisticated translation, almost every phase of the migration can be infl uenced with custom code. To create a data model mapping, follow these steps: 1. Create a new data model version. You must have at least two versions to create a mapping. 2. Choose the File ➪ New File (or any equivalent) command. 3. Select the Mapping Model template (in the Resource group). 4. Give the mapping document a name. I tend to name my mappings after the model and the versions it translates between, such as Accounts2to3.xcmappingmodel . a. Choose the project to which to add the mapping document. b. The location for the new document should be inside your project ’ s folder, preferably with the other data model documents. c. Choose the targets. Each target must also include both of the data models in question. 5. Xcode presents a dialog box similar to the one shown in Figure 15 - 20. a. In your project ’ s fi les, locate and select the old data model fi le. You will need to expand your data model group, because you have more than one version. b. Click the Set Source Model button. c. Select the new data model fi le. d. Click the Set Destination Model button. c15.indd 330c15.indd 330 1/21/10 3:52:30 PM1/21/10 3:52:30 PM Download at getcoolebook.com Xcode constructs a new mapping model document, and fi lls in the translations that look obvious to it. Your job is to supply anything that ’ s missing or needs to be customized. FIGURE 15-20 The mapping model document window, shown in Figure 15 - 22, is organized very much like the data model browser: the left column lists the entity mappings. Selecting an entity mapping displays the property mappings for that entity mapping in the middle column. On the right is a details pane where you set the specifi cs for the selected entity or property mapping. You can add or remove mappings using the + and – buttons/menus at the bottom of the columns. Order is sometimes important. Entity mappings are performed in a specifi c order, and if you have mappings that depend on previous mappings then that order may be signifi cant. To change the order, fi rst sort the entity mappings column by order (the # column). You can then drag entity rows into the sequence you desire. Most of the details concern how entities are mapped to other entities, and how the attributes of new objects are determined using the content of old objects. One fi eld of note is the Custom Policy property of an entity mapping. A custom migration policy object is a subclass of NSEntityMigrationPolicy. It receives a series of messages as the various migration phases are performed, allowing you to inject custom code into the process. Enter the name of your custom subclass of NSEntityMigrationPolicy into the fi eld. Core Data creates an instance of your class and lets it participate in various aspects of entity migration. Migrating Data Schemas ❘ 331 c15.indd 331c15.indd 331 1/21/10 3:52:36 PM1/21/10 3:52:36 PM Download at getcoolebook.com 332 ❘ CHAPTER 15 DATA MODELING An example serves as a good explanation. Let ’ s say you have a Core Data project that is just getting started. You begin by defi ning a User entity that has firstName , lastName , location , and email attributes. It ’ s a good start, and you ’ ve entered some data into your database, but you quickly realize that location is vague and really should have been country , and the e - mail addresses should have been a separate table so you can relate multiple accounts that use the same e - mail address. You continue development, following these steps: 1. Open the current data model. Make sure it ’ s saved. Choose Design ➪ Data Model ➪ Add Model Version. 2. Open the new data model ( BigBrother_DataModel 2 ). 3. Select the User entity mapping. Rename the location attribute to country . 4. Remove the email attribute from User. 5. Create a new Email entity. 6. Add an emailAddress attribute to the new entity. 7. Return to the User entity and add a new to - one relationship, name it email , and choose Email as the destination entity. Your model should now look like the one in Figure 15 - 21. 8. Save the model and choose Design ➪ Data Model ➪ Set Current Version. 9. Make whatever code and nib document changes are needed to work with your new data model. FIGURE 15-21 c15.indd 332c15.indd 332 1/21/10 3:52:41 PM1/21/10 3:52:41 PM Download at getcoolebook.com At this point, you ’ ve created a new version of your data schema and application. Unfortunately, the data you already entered is in the old version and can no longer be read. Launching your application at this point would simply result in Core Data errors. You construct a mapping to convert the data in the old schema into the new one: 10. Choose File ➪ New File, select the Mapping Model template, and name it BigBrother1to2.xcmappingmodel . You then edit your migration mapping to fi ll in the missing pieces: 11. Handle the attribute rename by selecting the UserToUser mapping, and then selecting the county attribute mapping. Set its value expression to $source.location . This copies the value of the location attribute from the old User to the country attribute in the new User. 12. Select the Email entity mapping. Change the source from nothing to User. This now creates a new Email entity for every User entity in the old database. (There are now two mappings for the User entity, so every old User object is processed twice — once to make a new User and again to make a new Email.) 1 3. Select the emailAddress attribute mapping of the new UserToEmail mapping. Enter a value expression of $source.email . This copies the email attribute of the old User entity into the emailAddress attribute of the new Email entity. 1 4. Select The UserToUser entity mapping, and then select the email attribute mapping. Under the Auto Generate Value Expression, enter a KeyPath of $source and Mapping Name of UserToEmail, as shown in Figure 15 - 22. This sets the email relationship in the new User object to the single object created by the UserToEmail mapping (that is, the new Email object). FIGURE 15-22 Migrating Data Schemas ❘ 333 c15.indd 333c15.indd 333 1/21/10 3:52:42 PM1/21/10 3:52:42 PM Download at getcoolebook.com 334 ❘ CHAPTER 15 DATA MODELING 1 5. Add the following code to your application ’ s data store setup: NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 16. Pass the newly created options object in the - addPersistentStoreWithType: configuration:URL:options:error: message during startup. Your application is now ready to run. When it starts, Core Data detects that your current data model does not agree with the structure of your existing store. It automatically fi nds the older version of the data schema that does, fi nds the mapping that maps between those two models, applies the mapping, and updates your data store. CREATING NSMANAGEDOBJECT SUBCLASSES The beginning of this chapter mentioned that the entities you defi ne in your data model exist as instances of NSManagedObject at run time. Quite often, NSManagedObject is more than suffi cient for your needs. You might, however, need a class with more specialized functionality for many reasons: Localized business logic in the entity object Specialized or complex validation Custom pre - or post - processing of attribute changes Non - standard attribute types There are also a number of reasons why you wouldn ’ t need to subclass NSManagedObject: Provide attribute property storage Use any of the built - in Core Data property features Inherit properties from other entities Use Key Value Coding, Key Value Observing, or Bindings An NSManagedObject reads a description of its entity and dynamically synthesizes real Objective - C accessor methods at run time. The result is an object that, for all intents and purposes, is identical to a custom class that defi nes those properties in code. As an example, an NSManagedObject for an entity that defi nes a string name attribute property would be functionally identical to a custom class that implemented accessors compatible with a @property NSString* name directive. You can send either object - name and - setName: messages, watch for changes using Key Value Observing, and so on. Ask yourself if you really need to subclass NSManagedObject before continuing. To create a custom implementation class for an entity, start by subclassing NSManagedObject. You cannot use just any arbitrary class; your class must be a subclass of NSManagedObject. The easiest way to get started is to use the Managed Object Class fi le template. This template appears only ➤ ➤ ➤ ➤ ➤ ➤ ➤ ➤ c15.indd 334c15.indd 334 1/21/10 3:52:42 PM1/21/10 3:52:42 PM Download at getcoolebook.com . lets it participate in various aspects of entity migration. Migrating Data Schemas ❘ 33 1 c15.indd 33 1c15.indd 33 1 1/21/10 3: 52 :36 PM1/21/10 3: 52 :36 PM Download at getcoolebook.com 33 2 ❘ CHAPTER. object). FIGURE 15-22 Migrating Data Schemas ❘ 33 3 c15.indd 33 3c15.indd 33 3 1/21/10 3: 52:42 PM1/21/10 3: 52:42 PM Download at getcoolebook.com 33 4 ❘ CHAPTER 15 DATA MODELING 1 5. Add the following. corresponds to the new one. Migrating Data Schemas ❘ 32 9 c15.indd 32 9c15.indd 32 9 1/21/10 3: 52 :30 PM1/21/10 3: 52 :30 PM Download at getcoolebook.com 33 0 ❘ CHAPTER 15 DATA MODELING If you didn ’ t

Ngày đăng: 04/07/2014, 06:20

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan