By Developers, For Developers

Historical errata for Core Data in Swift

PDF PgPaper PgTypeDescriptionFixed onComments
23TYPO

“Instead of having an add” logic path and anedit’’ logic path”

Excerpt From: Marcus S. Zarra. “Core Data in Swift (for Don Sleeter).” iBooks.
Near the end of the “The Recipe List” chapter

2016-03-28
27TYPO

The period is missing from the statement:

ingredient setValue(recipe, forKey:“recipe”)

2016-03-28
41ERROR

The code is shown for this method: canEditRowAtIndexPath

But the text describes this method: cellForRowAtIndexPath

The second one is far more useful, and if the edit method has some relationship to the use of the FRC, then it would be helpful to document both methods.

2016-03-28
42ERROR

This text: “there are two case statements” likely refers to something (I’m guessing) from the Objective-C version of the book. It should read “the default case…”

2016-03-28
allSUGGEST

It would be nice if the book could explain what (if any) gotchas or special techniques are used/necessary to handle a recursive tree-structured object model in Core Data. The only mention of recursion I find is in the JSON conversion section.

2016-03-30
allSUGGEST

Similar to the choice between using Interface Builder vs creating the UI in code, it would be nice if the book could address building object models in code rather than using Xcode to define the model. Is this even possible?

2016-03-30
12ERROR

The text states:

Note that the block accepts both an NSString and an NSError pointer.

The Swift code its accepting a String and throws an error.

2016-03-28
22ERROR

The methods for configuring the persistent store are all described as Obj-C methods, not Swift methods.

Such as “The last parameter, error, is used when something goes wrong with the addition of the NSPersistentStore.” Being this is Swift, we aren’t passing in a pointer but are wrapping the cal with the do-try-catch syntax.

2016-03-28
46TYPO

The books list the GitHub path to be github.com/mzarra/ZDS_Shared but it ends up being redirected to github.com/mzarra/MSZ_Shared. Not that it doesn’t work, just a bit confusing.

2016-03-28
47TYPO

The second method in the public API for the ZSContextWatcher

should be

The second method in the public API for the MSZContextWatcher

2016-03-28
51ERROR

When running the sample code in the PPRecipes folder, the Add Recipe screen already contains the Last Used and Author attributes. Attempting to manipulate either of those is causing an NSInternalInconsistencyException to be thrown. (‘NSFetchRequest could not locate an NSEntityDescription for entity name ’Author’).

2016-03-29
58ERROR

The text in the “Turning on Automatic Data Migration” states: To do this, we need to make a small change to the persistentStoreCoordinator method in our AppDelegate. The code to manage the PSC is in PPRDataController, not the AppDelegate. Also these method listed is showing it in Obj-C selector form, not Swift.

2016-03-28
65 TYPO

The text currently reads:

NSEntityMigrationPolicy is designed to be subclasses so that we can override all or part of the migration.

Should read:

NSEntityMigrationPolicy is designed to be subclassed so that we can override all or part of the migration.

2016-03-28
64TYPO

Currently reads:

Next, we need to modify the RecipeIngredientToRecipeIngredient.

Should read:

Next, we need to modify the RecipeIngredientToRecipeIngredient mapping.

2016-03-28
82ERROR

The section “How to Load Property Values and NSManagedObjectID Objects” shows sample code which is the exact same code described on page 80 to load just the managed object ids:

let request = NSFetchRequest(entityName: “Person”)
request.resultType = .ManagedObjectIDResultType

2016-03-28
83SUGGEST

The text reads: It is far more efficient for us to use that NSPredicate against a collection that is already in memory.

It seems to me that it should be: It is far more efficient for us to use an NSPredicate against a collection that is already in memory.

The references “that NSPredicate” but we haven’t really been talking about an NSPredicate at this point.

2016-03-28
94 SUGGEST

The text states: In addition to object handle off between queues (the passing of an object ref- erence from one queue to another)…

I’m thinking that you actually mean:

In addition to object hand off between queues (the passing of an object ref- erence from one queue to another)…

2016-03-28
95TYPO

let center = NSNotificationCenter.defaultCenter()

appears twice, one right after each other, in the code snippet.

2016-03-28
115TYPO

Errant period.

Nothing gets loaded into memory and therefore the API is executed very quickly. just slightly slower than SQLite itself.

Should be a comma before “just slightly slower”

2016-03-28
131TYPO

The aggregsateNetworkCall(length: duration:) can use any system that makes sense to the business needs of the application.

Should be aggregateNetworkCall(

2016-03-28
121TYPO

fatalError(“Unexpected result frmo executeRequest”)

“frmo” should be “from”

2016-07-02
5TYPO

s/seques/segues/

2016-07-02
6TYPO

s/Unidetified/Unidentified/

2016-07-02
11SUGGEST

I would request that you make an effort to update the screenshots for this new edition. I am experiencing cognitive dissonance when I see screenshots with the look and feel of UIKit as it was before iOS 7, and seeing code in Swift. To me, those screenshots scream Objective-C and some readers (not me!) may question whether the content is really up to date when they see those screenshots.
I pointed to the one on page 11 as a glaring example, with that canvas texture in the background.

The same is also true for Xcode screenshots (see page 34 of the PDF). It is most striking when the one in page 62 is a modern Xcode screenshot. While I know that if the screenshot is maintained it is because it is still valid, it is quite distracting all the same.

2016-07-02
127OK

I am getting a compiler error when I use “finished = true” in override func start:
Cannot assign to property:‘finished’ is a get-only property.

2016-07-02Please review the source code and you will find that the finished variable is overridden in the class file.
19OK

“What this means is that we can create a new controller that is a subclass of NSObject and place all of the Core Data related code into that controller.”

Actually, it could well not be a subclass of NSObject. Making the controller an ObjC compatible object would have us losing potentially desirable Swift properties, like method overload, that are not available in ObjC.

2016-07-02I tried that route and ended up keeping it an NSObject subclass to gain many of the benefits from KVO and notifications.
39OK

In prepareForEditRecipeNameSegue, in PPREditRecipeViewController, why not require the parameter type to be the type checked by the guard statement, and remove the need for the guard statement completely? I may not have read ahead enough if there is future reason for it, but as it is, it’s unnecessary type checking when the type system can do that for you.

2016-07-02That would only move the guard up to the `prepareForSeque` which would be messy.
56TYPO

On pg 56 of PDF, .first is used to get the documentsURL, but on pg 57 the text says “We call ‘last’ on that array…” when describing the code.

2016-07-02
4SUGGEST

The Storyboard screenshots appear not to be have been updated since pre-iOS 7 times. This can give the impression that the book is out of date which is not the case. Would be good if they can be redone using Xcode 7.

2016-07-02
149ERROR

The description for MSZContextWatcher says:

“The goal of the MSZContextWatcher is to provide us with the ability to monitor a subset of the data that is in Core Data and to be notified when it CHANGES. It’s the same functionality that is in the NSFetchedResultsController but not as tightly coupled with the UITableView.”
(emphasis mine)

yet the init method calls:

center.addObserver(self, selector: “contextUpdated:”,
name: NSManagedObjectContextDidSaveNotification, object: nil)

not:

center.addObserver(self, selector: #selector(contextUpdated(_:)),
name: NSManagedObjectContextObjectsDidChangeNotification, object: nil)

and so contextUpdated: is only called on a save, not when something is updated

note: page number is for the ePub version as viewed in iBooks on the Mac using default viewing options

2016-07-02
154ERROR

MSZContextWatcher uses the following test in its contextUpdated() method:

if let insert = info?[NSInsertedObjectsKey] as? [NSManagedObject] {

however, the user info passed by NSManagedObjectContextObjectsDidChangeNotification (see my previous erratum) does not include arrays of NSMangeObjects, but rather Sets of NSMangedObjects. Thus, the code within the if statement is never called.

Instead, this check (and the other 2) should be:

if let insert = info?[NSInsertedObjectsKey] as? Set {

note: page number is based on the ePub version as viewed in iBooks for Mac with default viewing options

2016-07-02
4ERROR

Fresh download of the code, running in latest OS X, XCode 7.3.1. I open PRRecipes and build. In PPRMasterViewController.swift I get the following 5 errors (all the same one) ‘Cannot force unwrap value of non-optional type ’NSIndexPath’. Lines 159, 162, 166, 167, 170. Fixed by removing the exclamation from the ‘ip’ and ‘nip’.

Build continues, iPhone 6s Plus simulator, iOS 9.3, on start I get ‘dyld_fatal_error’

dyld: Library not loaded: @rpath/libswiftCore.dylib
Referenced from: /Users/alun/Library/Developer/CoreSimulator/Devices/235F8CB7-A885-4F2A-9D13-98ED14D0EBE0/data/Containers/Bundle/Application/E3BE8F6A-8740-44C6-958F-C55BC386E611/PPRecipes.app/PPRecipes
Reason: image not found

Still pretty new to Swift, so this may be obvious, but not to me. It may be relevant that at one point I downloaded the latest XCode beta with Swift 3, but later deleted it and reinstalled the current xcode/ Swift 2.3

2016-11-29
4ERROR

Further to my first report, I can solve the dyld error by going to the project build settings and finding ‘Embedded Content Contains Swift Code’ and changing that from ‘no’ to ‘yes. I did that for both PRRecipes target and the project, then did a clean before retrying. Now the project starts in the simulator, but if it click on Type:Entree in the first screen I get an error ’Unidentified seque’ from PPREditRecipeViewController.swift line 86. Checking with the switch, I thought this should probably be ‘selectRecipeType’, so went to the storyboard, found that segue (which does indeed lack an identifier, and added that one in. saved the storyboard, clean and rebuild. Deleted app from simulator, ran again.

This part now runs. Edit ingredients. Click Edit menu, this gives me an option ‘Add Ingredient’. I click on the green cross, and get a crash: <NSManagedObject 0x7fea8908cad0> valueForUndefinedKey:]: the entity RecipeIngredient is not key value coding-compliant for the key “ingredient”.’
That’s as far as I have got. Am I missing something obvious?

2016-11-29
16TYPO

Let’s look at how that that (—> should be removed) data model was created.

2016-11-29
50TYPO

Design > Data Model > Add Model Version

This path appears to be wrong. The correct path for Xcode 7 and Xcode 8 would be:
Editor > Add Model Version…

The same is true for page 30:
Design > Data Model > Add Fetch Request should be Editor > Add Fetch Request

2016-11-29
98TYPO

In the code, the description of the last fatalError should be “To-one relationship with malformed JSON” instead of “To-many relationship with malformed JSON”

2016-11-29
19TYPO

In the code at the top of the page, the URLsForDirectory method calls ‘first’ on the array. In the text below, that is explaining the code, says that we are to call ‘last’ on the array. A) One of these is a typo B) Can you reply with what the correct answer is and why? Thanks! Great book!

2016-11-29
143ERROR

The OSx version (in the PPRecipies project under shared/desktop), it crashes when starting up with the following error.

[<PPRecipes.PPRDataController 0x608000063280> valueForUndefinedKey:]: this class is not key value coding-compliant for the key managedObjectContext.

2016-11-29
143ERROR

To fix #80650 error, change mainContext to managedObjectContext (or change all of the links). Then it will work. All of the links in the nib file still think the mainContext is called managedObjectContext.

2016-11-29
1ERROR

Running from downloaded source code with no changes:
PPRecipes.xcodeproj . The ‘Add Recipe’ View -> ‘Type’ row, when clicked on produces error:

fatal error: Unidentified segue: file /Users/username/Downloads/code/PPRecipes/PPRecipes/PPREditRecipeViewController.swift, line 86
(lldb)

Exact line of code in program is: override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
guard let identifier = segue.identifier else {
fatalError(“Unidentified segue”)
}

2016-11-29
1ERROR

Running PPRecipes on iPhone6s Plus.

Steps: Recipes -> ‘’ -> Ingredients -> Edit -> ’’ Add Ingredient

Traceback Error:

2016-09-13 05:42:40.259 PPRecipes[3085:295396] Can’t find keyplane that supports type 4 for keyboard iPhone-PortraitTruffle-NumberPad; using 675849259_PortraitTruffle_iPhone-Simple-Pad_Default
2016-09-13 05:43:12.054 PPRecipes[3085:295396] * Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[<NSManagedObject 0x7fdf8c8dba40> valueForUndefinedKey:]: the entity RecipeIngredient is not key value coding-compliant for the key “ingredient”.’

* First throw call stack:
(
\t0 CoreFoundation 0x000000010af3cd85 __exceptionPreprocess + 165
\t1 libobjc.A.dylib 0x000000010cce0deb objc_exception_throw + 48
\t2 CoreFoundation 0x000000010af3c9c9 -[NSException raise] + 9
\t3 CoreData 0x000000010ab33851 -[NSManagedObject valueForUndefinedKey:] + 289
\t4 PPRecipes 0x000000010a4c1dfb TFC9PPRecipes36PPRAddRecipeIngredientViewController14viewWillAppearfSbT + 331
\t5 PPRecipes 0x000000010a4c2381 TToFC9PPRecipes36PPRAddRecipeIngredientViewController14viewWillAppearfSbT + 49
\t6 UIKit 0x000000010b9052bd -[UIViewController _setViewAppearState:isAnimating:] + 710
\t7 UIKit 0x000000010b905958 -[UIViewController __viewWillAppear:] + 149
\t8 UIKit 0x000000010b935750 -[UINavigationController _startCustomTransition:] + 1203
\t9 UIKit 0x000000010b945b9b -[UINavigationController _startDeferredTransitionIfNeeded:] + 712
\t10 UIKit 0x000000010b946d0b -[UINavigationController __viewWillLayoutSubviews] + 57
\t11 UIKit 0x000000010baf5503 -[UILayoutContainerView layoutSubviews] + 248
\t12 UIKit 0x000000010b81f980 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 703
\t13 QuartzCore 0x000000010fdadc00 -[CALayer layoutSublayers] + 146
\t14 QuartzCore 0x000000010fda208e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
\t15 QuartzCore 0x000000010fda1f0c _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
\t16 QuartzCore 0x000000010fd963c9 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
\t17 QuartzCore 0x000000010fdc4086 _ZN2CA11Transaction6commitEv + 486
\t18 QuartzCore 0x000000010fdc47f8 ZN2CA11Transaction17observer_callbackEP19_CFRunLoopObservermPv + 92
\t19 CoreFoundation 0x000000010ae61c37 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23
\t20 CoreFoundation 0x000000010ae61ba7 __CFRunLoopDoObservers + 391
\t21 CoreFoundation 0x000000010ae577fb __CFRunLoopRun + 1147
\t22 CoreFoundation 0x000000010ae570f8 CFRunLoopRunSpecific + 488
\t23 GraphicsServices 0x000000010f195ad2 GSEventRunModal + 161
\t24 UIKit 0x000000010b764f09 UIApplicationMain + 171
\t25 PPRecipes 0x000000010a4ddd32 main + 114
\t26 libdyld.dylib 0x000000010d7ad92d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

2016-11-29
1ERROR

Downloaded from source code, PPRecipes, error thru:

Recipes -> ‘’ -> Ingredients -> Edit -> ’’ Add Ingredient

Traceback:

2016-09-14 03:41:15.698 PPRecipes[4995:401145] * Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[<__NSCFString 0x7fb13a554480> valueForUndefinedKey:]: this class is not key value coding-compliant for the key unitOfMeasure.’

* First throw call stack:
(
\t0 CoreFoundation 0x0000000103a77d85 __exceptionPreprocess + 165
\t1 libobjc.A.dylib 0x000000010581bdeb objc_exception_throw + 48
\t2 CoreFoundation 0x0000000103a779c9 -[NSException raise] + 9
\t3 Foundation 0x0000000103edc144 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 226
\t4 Foundation 0x0000000103e32167 -[NSObject(NSKeyValueCoding) valueForKey:] + 280
\t5 PPRecipes 0x0000000102ffd080 TFC9PPRecipes36PPRAddRecipeIngredientViewController14viewWillAppearfSbT + 960
\t6 PPRecipes 0x0000000102ffd391 TToFC9PPRecipes36PPRAddRecipeIngredientViewController14viewWillAppearfSbT + 49
\t7 UIKit 0x00000001044402bd -[UIViewController _setViewAppearState:isAnimating:] + 710
\t8 UIKit 0x0000000104440958 -[UIViewController __viewWillAppear:] + 149
\t9 UIKit 0x0000000104470750 -[UINavigationController _startCustomTransition:] + 1203
\t10 UIKit 0x0000000104480b9b -[UINavigationController _startDeferredTransitionIfNeeded:] + 712
\t11 UIKit 0x0000000104481d0b -[UINavigationController __viewWillLayoutSubviews] + 57
\t12 UIKit 0x0000000104630503 -[UILayoutContainerView layoutSubviews] + 248
\t13 UIKit 0x000000010435a980 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 703
\t14 QuartzCore 0x00000001088e8c00 -[CALayer layoutSublayers] + 146
\t15 QuartzCore 0x00000001088dd08e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
\t16 QuartzCore 0x00000001088dcf0c _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
\t17 QuartzCore 0x00000001088d13c9 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
\t18 QuartzCore 0x00000001088ff086 _ZN2CA11Transaction6commitEv + 486
\t19 QuartzCore 0x00000001088ff7f8 ZN2CA11Transaction17observer_callbackEP19_CFRunLoopObservermPv + 92
\t20 CoreFoundation 0x000000010399cc37 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23
\t21 CoreFoundation 0x000000010399cba7 __CFRunLoopDoObservers + 391
\t22 CoreFoundation 0x00000001039927fb __CFRunLoopRun + 1147
\t23 CoreFoundation 0x00000001039920f8 CFRunLoopRunSpecific + 488
\t24 GraphicsServices 0x0000000107cd0ad2 GSEventRunModal + 161
\t25 UIKit 0x000000010429ff09 UIApplicationMain + 171
\t26 PPRecipes 0x0000000103018d42 main + 114
\t27 libdyld.dylib 0x00000001062e892d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

2016-11-29
43-44TYPO

The book section entitled “Building Our Own: MSZContextWatcher”, subsection “init()”, adds an observer for NSManagedObjectContextObjectsDidChangeNotification (In Swift 3.0 it would be NSManagedObjectContextObjectsDidChange). the change notification is also in the source code.

I am conflicted by a subsequent subsection in the book entitled “contextUpdated()” that states: “Now when we receive a notification from an NSManagedObjectContextDidSaveNotification”.

This caught me by surprise because I would have expected the same NSNotification. I am asking here for definitive clarification with the hope that this may help the book. Sure hope I am not being completely oblivious.

2016-11-29
29ERROR

let results = [NSManagedObject]? = nil
should be replaced by
var results = [NSManagedObject]? = nil
to make it mutable.

36SUGGEST

In Chapter 2, section Loading the Data Model, the data controller is described as being a subclass of NSObject but the code downloaded from the pragmatic bookshelf website (dated January 3 in the subfolder PPRecipes) is not a subclass of NSObject. The downloaded code does compile and run, so it’s not clear why the Controller described in the book needs to inherit from NSObject.

Also note that the website requires a page number but I’m using the epub version where pagination depends on window size.

Categories: