By Developers, For Developers

Historical errata for Core Data

PDF PgPaper PgTypeDescriptionFixed onComments
47TYPO

Section: “Faulting and Disk Access”

Paragraph: “Likewise, faulting an NSManagedObject…”

Should “faulting” be replaced by “saving”?

2012-11-06
10TYPO

In the third paragraph you say: “It is not just the persistence on desk,” and by desk I assume you mean disk?

2012-11-19
10TYPO

“It is not just the persistence on desk,” should probably read “It is not just the persistence on disk,”

2012-11-19
139ERROR

In step 2, at the bottom, it says, “… change the name in the Identity inspector in Interface Builder, and change the identity Name field.” This now is called the “Label” under the “Document” section of the Identity inspector.

2012-11-19
11ERROR

The data model files in the source code are corrupt and cannot be opened. Downloaded several different copies all with the same result. I was using Xcode 4.5 & OS X 10.7

.xcdatmodeld 2012-11-12 11.5:05:07.216 momc[56884:70b] * Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘* -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive

2012-11-19
90ERROR

" there are two recommended methods for using Core Data across multiple threads. The first method, "
Mention to the second method is due in this paragraph.

2012-12-14
195SUGGEST

You say: “Core Data is generally considered to be a single-user/single-application persistent store. However, as we explored in Chapter 6, Using iCloud, on page 103, Core Data can be used beyond the single-user/single-application design.”

Maybe I haven’t had enough coffee this morning, but that sounds confusing. iCloud is inherently single-user. It can be multi-application to a limited extent, but is generally single-application.

So … the way you word things makes it sound like multi-user / multi-application support was discussed in the iCloud chapter. But I dont’ see that.

Again, maybe not enough coffee. But I thought I’d pass this trivial comment on while thinking about it :)

2012-12-14
110ERROR

You say: “With the release of iOS 6.0 and Mac OS X 10.8 Mountain Lion, a number of new features have been added to Core Data. One of the more interesting changes was the introduction of parent and child contexts.”

BUT — Parent / Child contexts were introduced in iOS 5.0 / OS X 10.7

2012-12-14
11096ERROR

I just pointed out a specific case where you said parent / child contexts were introduced in iOS 6 / OS X 10.8, when in fact it was iOS 5 / OS X 10.7.

I just realized that these errors are repeated throughout section 5 (and maybe beyond). There are quite a few places that mention, “With iOS 6…” when it should be iOS 5.

2012-12-14
19SUGGEST

Just a suggestion but maybe it would be better if the example code here was for iOS and not OS X? Up to this point the discussion and examples have focussed on iOS so it seems to jar a little when NSApplication makes an appearance:

> In that situation, we ask the NSApplication to present the error for us and return.

2012-12-14
115TYPO

Debug output

As we discussed in Chapter 1, Under the Hood of Core Data, on page 1, we can turn on a debugging parameter so that we can watch all of the SQL that Core Data generates while it is accessing the SQLite file. In addition to that setting, we can also turn on an additional setting to watch all of the chatter between Core Data and iCloud. That additional setting is com.apple.coredata.ubiq-

uity.logLevel. For an unknown reason, this logging code only responds to level 3, as shown in Figure 22, Turning on iCloud Debugging, on page 115.

There is no reference to the debugging on page 1

2012-12-14
100TYPO

2nd pp, 2nd sentence: “When the main has finished … see if it needs a change.” The “needs a change” should either be something like: “has changes” or “also needs saving.”

2012-12-14
70SUGGEST

The text reads “I used Apple’s demonstration application from WWDC called GoFetch. (The source code for this application is available as part of the ADC Headstart package for Core Data.)”

Suggestion: Can you verify that Apple still offers coding headstarts, and specifically the Core Data coding headstart? I’ve searched their developer.apple.com website and can’t find a link to it.

2012-12-14
81SUGGEST

In the code for “Baseline/PPRecipes/PPRImportOperation.m”, you use the call [self mainContext]. It’s not clear where “mainContext” is declared or from where it originates.

2012-12-14
86SUGGEST

In the paragraph “The initializer for our export operation needs to retain only the NSManagedObjectID of the incoming NSManagedObject. Because the initWithRecipe method is being called on the thread on which the incoming NSManagedObject was created, we can access its methods. Once we are in our own -main method, we can no longer access it. However, the NSManagedObjectID is thread-safe, and can cross the boundary. So we grab it now, and hold onto it in a property.”, can you explain why you pass the NSManagedObject instead of the NSManagedObjectID into the NSOperation?

2012-12-14
1SUGGEST

It would be appreciated if you peoples can share knowledge about many to many relationship in detail

2012-12-14
95TYPO

[self setValue:childSet forKey:key];

This line of code is VERY likely not what’s wanted here (it’s broken). Calling setValue on “self” refers to the PPRImportOperation.

My change to the code was :

[mo setValue:childSet forKey:key];

This calls the setValue method on the Managed object.

18/26SUGGEST

I’ve been unable to run the sample code because of the lack of initialization of the data base. I could not find a section of the book or notes in the code explaining what had to be done to set things up. I did see some shell scripts, but no context in how to run them. A Readme file in the sample code is essential.
pdj

67TYPO

In the book on page 67/336 in the code for ZSContextWatcher.m, the sample shows,

NSPredicate *final = nil;

Where in the Github copy of ZSContextWatcher.m on line 54 it is,

NSPredicate *finalPredicate = …

Further, the subsequent sample code in the book assumes the the object is “finalPredicate”, not “final”,

if (![self masterPredicate]) {​​
 \t
​​ [self setMasterPredicate:finalPredicate];

39ERROR

The creation of the UIAlertView is done within the dispatch_async block on the global queue, which causes an error. It should be done on a block that’s run on the main UI queue.

29ERROR

These two lines are not correct:

NSArray *newArray = [NSArray arrayWithObject:newIndexPath];
NSArray *oldArray = [NSArray arrayWithObject:indexPath];

arrayWithObject raises an error if its argument is nil, which both of these can be depending upon the mutation type.

29TYPO

[REF: Pete Hopkins B4 Note]

Within the first printing the tech. error noted by Pete Hopkins in B4 still remains.

NSArray *newArray = [NSArray arrayWithObject:newIndexPath];
NSArray *oldArray = [NSArray arrayWithObject:indexPath];

arrayWithObject raises an error if its argument is nil, which both of these can be depending upon the mutation type.

-Nathan Berendt

43TYPO

Screen shots of data models are equal, screen shot for version 2 is missing the Author entity and the lastUsed property.

34ERROR

finalPredicate never declared either in the class or within the local method scope. You might want to check the code being posted on media.pragprog.com too.

2814TYPO

In Chapter 1. Under the Hood of Core Data, subsection Property Accessors there is a wrong reference in the following text:


Relationships can use properties, just like the attributes discussed earlier.
In the code in Mutable Access of To-Many Relationships, on page 13, if we want to add a property to retrieve the relationship, we declare the following property:

@property (strong) NSSet *recipeIngredients;


Instead of “Mutable Access of To-Many Relationships, on page 13” the reference should be to “Accessing a To-Many Relationship, on page 13”. The property recipeIngredients is NOT mutable.

211TYPO

At the bottom of the page it says “seques” instead of “segues”.

9ERROR

NSManagedObjectContext … Therefor, we hand off the reference to it to our AppDelegate so the the rest of the application can access it.

This is great but in the examples you don’t do this.

//
// PPRAppDelegate.h
// PPRecipes
//
// Created by Marcus Zarra on 4/3/12.
// Copyright © 2012 The Pragmatic Programmer. All rights reserved.
//

@interface PPRAppDelegate : UIResponder

@property (strong, nonatomic) UIWindow *window;

- (void)saveContext;

@end

—- and part of the .m file

#import “PPRAppDelegate.h”

#import “PPRMasterViewController.h”
#import “PPRImportOperation.h”

@interface PPRAppDelegate()

@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

@property (nonatomic, strong) NSURL *fileToOpenURL;

- (void)initializeCoreDataStack;
- (void)contextInitialized;

- (void)consumeIncomingFileURL:(NSURL*)url;

@end

@implementation PPRAppDelegate

synthesize window; synthesize managedObjectContext;
@synthesize fileToOpenURL;

I’m use MVCS and the store needs access to the moc I recommend something like this: in the .h

#define ApplicationDelegate ((AppDelegate *)[UIApplication sharedApplication].delegate)

@interface AppDelegate : UIResponder

@property (strong, nonatomic) UIWindow *window;

// Notice how this is called mainManagedObjectContext all the local instances are called
// ManagedObjectContext this is because core data is not thread safe and each access into it needs to be on the thread that calls it.
@property (strong, nonatomic) NSManagedObjectContext *mainManagedObjectContext;

//This is new it is thread safe
- (void)saveContext;

and in .m change to:

@interface AppDelegate()

//Place the private methods in this category

- (void)initializeCoreDataStack;
- (void)contextInitialized;

@end

#pragma mark - Core Data stack

- (void)initializeCoreDataStack
{
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:"GAIGAgent" withExtension:“momd”];
ZAssert(modelURL, @“Failed to find model URL”);

NSManagedObjectModel *mom = nil;
mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
ZAssert(mom, @“Failed to initialize model”);

NSPersistentStoreCoordinator *psc = nil;
psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
ZAssert(psc, @“Failed to initialize persistent store coordinator”);

NSManagedObjectContext *moc = nil;
NSManagedObjectContextConcurrencyType ccType = NSMainQueueConcurrencyType;
moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:ccType];
[moc setPersistentStoreCoordinator:psc];
//[self setManagedObjectContext:moc];
self.mainManagedObjectContext = moc;

…

so basically make the mainManagedObjectContext accessible so the rest of the app can use it.

The way you have it does work when you set the mod up in the didFinishLaunchingWithOptions but this is not usable when using the MVCS pattern were all the data goes thru the store and thus the store needs access to the “main” moc

92ERROR

Book describes

5.5 Parent-Child NSManagedObjectContext Instances
With the release of iOS 6.0 and Mac OS X 10.8 Mountain Lion, a number of new features have been added to Core Data.

I believe these features were introduced with iOS 5.0 / Mac OS X 10.7. Certainly is seems -performBlock: and -performBlockAndWait: are available in iOS 5.0. I can’t provide a link to docs as your form prevents it.

20SUGGEST

Under the section on StoreFetchedRequests, the code snippet includes an example of using NSSortDescriptors, which are not covered until the next section. This isn’t a huge problem, but it’s a little confusing for a new user who’s following the code particularly - especially since the accompanying text basically ignores the presence of the sort descriptors (rather than using them as a segue into the following section, which would probably be the most natural way of using the code snippet).

As a newcomer to Core Data myself, I found this section confusing for several minutes as I was trying to make a connection between the two separate concepts I saw in the code - when in fact the “second” topic was waiting for me on the following page.

IMO, these last two lines should either be omitted or (ideally) used as a natural segue into the following section.


RecipesV1/PPRecipes/PPRSelectIngredientTypeViewController.m
NSManagedObjectContext *moc = [self managedObjectContext]; NSPersistentStoreCoordinator *psc = [moc persistentStoreCoordinator]; NSManagedObjectModel *model = [psc managedObjectModel];
NSFetchRequest *request = [model fetchRequestTemplateForName:@“allIngredients”];

/*BEGIN*/

NSMutableArray *sortArray = [NSMutableArray array];
[sortArray addObject:[[NSSortDescriptor alloc] initWithKey:@“name”
ascending:YES]];
[request setSortDescriptors:sortArray];

/*END*/

47TYPO

“NSEntityMigrationPolicy is designed to be subclasses…”

“Subclasses” should be “subclassed”.

63SUGGEST

5th Paragraph. Text mentions to “turn on external binary storage,” however the corresponding image referenced (figure 13, pg. 64) shows the “external record flag” checkbox selected. Since that is a setting for Spotlight, it would make more sense to show the “Allows External Storage” checkbox selected in this image.

219TYPO

Last line in the page begins with “The seques of this UIViewController.”

It should be “The segues of this UIViewController.” (i.e. segues instead of seques).

35ERROR

(Or a suggestion)
1) The results mDictionary is local to -contextUpdated and never assigned/passed so how does it “…pass the newly created NSDictionary to our delegate.”? (p. 36)
2) Also the book code version has action in the class extension (changed in the one on GitHub) and it’s never set in the existing code.

Were these meant to just be starter code that has to be amended to be functional? The book presentation suggests otherwise but certainly could have misinterpreted that.

86ERROR

In the first code example on the page, this line is incorrect:
[dict addEntriesFromDictionary:[self moToDictionary:childMO]];

It should read:
[dict setValue:[self moToDictionary:childMO] forKey:key];

Otherwise, the resulting NSDictionary will be a combination of keys and values from multiple entities, which is incorrect.

229222ERROR

I’m using Xcode 4.6.2. I’m having problems with your nifty Macros. Note: I have actually manually typed in the Macros (you provide in Appendix 2) into the -Prefix.pch file after the Cut & Paste method raised some Compile Type Errors. But I’m receiving the same Compile Time Errors regardless of how I try to incorporate them into the .pch file. The errors are associated with (and localized within) the ALog() and ZAssert() macros. If I don’t try to compile the manually entered content I don’t receive any hints of any problem. Once I BUILD the source the same 5 Errors appear that I had before. Everything “looks” good, but the compiler is telling me otherwise. I’m kind of stumped. I can email the offending 5 lines of source code if that helps.

221TYPO

Reading ePub version, so page number won’t work. Chapter 3.5, last paragraph: “Is it of vital importance…”

I think it should be: “It is of vital importance…”

26TYPO

In the section on wiring up the UITableView (“Wiring the NSFetchedResultsController to a UITableView”), the data source protocol is referred to as UITableViewDatasource, when the protocol is actually called UITableViewDataSource.

20TYPO

The screenshot shows a highlighted fetch request name “bigMeals”. The code snippet below it calls for “allIngredients”.

3,10ERROR

Sec 1.4 The interface property for “serves” should be a NSUInteger type instead of an NSString. This would be consistent with the CD model presented in Figure 2 in Sec 1.1.

82ERROR

Since this is all about getting the export off the main thread, adding the export operation to the mainQueue makes no sense. (The import code has the same problem.)

86ERROR

If the lastUsed attribute of the Recipe entity is set, JSON serialization will fail here, since NSDate isn’t supported.

63TYPO

Figure 13 is named “Turn on the external record flag,” which suggests the Spotlight flag. Combined with the previously-noted fact that the figure shows the “Store in External Record File” checkbox on, but “Allows External Storage” off, this is very confusing!

1TYPO

In the extract (no page numbers, so I entered “1”), under:
6.1 Introducing the UIManagedDocument, Manually Saving a UIManagedDocument,
I find:

[[self managedDocument] saveToURL:fileURL
forSaveOperation: UIDocumentSaveForCreating
completionHandler:^(BOOL success) {
//Handle failure
}];

UIDocumentSaveForCreating should be UIDocumentSaveForOverwriting, I’m pretty sure…

34TYPO

In the code snippet you define NSPredicate *final;
but then go on and use an undefined predicate called finalPredicate.

- (void)addEntityToWatch:(NSEntityDescription)description withPredicate:(NSPredicate)predicate;
{
NSPredicate *entityPredicate = nil;
NSPredicate *final = nil;
NSArray *array = nil;
entityPredicate = [NSPredicate predicateWithFormat:"entity.name == %",
[description name]];
array = [NSArray arrayWithObjects:entityPredicate, predicate, nil];
final = [NSCompoundPredicate andPredicateWithSubpredicates:array];
if (![self masterPredicate]) {
[self setMasterPredicate:finalPredicate]; return;
}
array = [NSArray arrayWithObjects:[self masterPredicate], final, nil];
finalPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:array];
[self setMasterPredicate:finalPredicate];
}

39ERROR

The `UIAlertView` is created and displayed from a background thread.

211TYPO

“Right now we are concerned with the seques of this UIViewController.” It should be “segues” instead of “seques.”

Categories: