Online Book Reader

Home Category

Learn Objective-C on the Mac - Mark Dalrymple [81]

By Root 1021 0
and validateForUpdate: methods, so the compiler knows how to deal with it properly. This method is a little more complicated than the single attribute validation method. We do the same sort of checking for a problem, returning YES if it’s okay, and otherwise constructing an NSError, setting the error parameter to point at it, and returning NO. However, in order to “play nice” with Core Data, we have to check for the existence of a pre-existing error, and if there is one, combine it with our own into a special kind of error. This lets Core Data eventually report back all the errors it finds when it tries to save. This error combining is done using another method of our own, errorFromOriginalError:error:, which we should add to our class:

Basically, this method checks the originalError parameter to see if it already contains multiple errors, and if so, just adds the new one to the list. Otherwise, it combines the two single errors into a new multiple error object.

With all that in place, you should now be able to compile and run, select a MythicalPerson, set their power above 50, their divinity below 100, and try to save. You’ll see an error telling you about the problem. You can also make sure that reporting of multiple problems works, by leaving this power/divinity inconsistency in place, changing the name to “Bob,” and trying to save. You should see a warning panel telling you that multiple validation errors occurred, but you don’t see details about any of them. This suggests a good idea for a future expansion of the app delegate’s saveAction: and applicationShouldTerminate: methods: come up with a way to display multiple errors instead of just calling presentError: as is currently done. There’s something to tackle on a rainy day!

Creating a Custom Attribute


Another common sort of simple “business logic” calls for the creation of custom attributes that are based on the values contained in an object’s attributes. For example, if you have an entity with firstName and lastName attributes, you might want to make a custom attribute called fullName that combines the two together.

This sort of thing is a piece of cake with Core Data. In our case, let’s say we want to add an attribute to MythicalPerson called awesomeness, which will be calculated from the MythicalPerson’s power, divinity, and goodness. We start off by defining a method called awesomeness in MythicalPerson’s implementation:

With that in place, you can call the awesomeness method on any MythicalPerson and get the result. This also works with Cocoa Bindings of course, so we can easily bind a GUI control’s value to this new property. Go back to Interface Builder, make the window and box a little bigger, and add a label and a level indicator from the Library window, something like you see in Figure 7-11.

Figure 7-11. MythBase, now with added Awesomeness!

Now select the Awesomeness control, and bring up the Attributes Inspector. Set the Style to Continuous, and the Minimum and Maximum to 0 and 1600, respectively. Now switch to the Bindings Inspector, and bind the level indicator’s Value via the Mythical Person Array Controller, with the controller key selection and the model key awesomeness. Note that Interface Builder doesn’t know anything about awesomeness, so you’ll have to type it in yourself instead of just picking it from the combo box; we’re sure you’ll agree that’s a small price to pay for awesomeness.

Save your changes, switch back to Xcode, Build & Run, and off you go. Switch between different rows in the table view, and you’ll see the bar of awesomeness change. Drag a slider and, now wait a minute; the awesomeness value doesn’t change! The reason for this is that no part of Core Data, not our model file, not our MythicalPerson class, not the controller we’re using, knows that awesomeness depends on other values, and needs to be recalculated if they change. This is fixed by implementing one more small method in MythicalPerson:

This is another method name that’s constructed dynamically based on an accessor name. We saw this

Return Main Page Previous Page Next Page

®Online Book Reader