[Swift 1] Day 16 - Code Exercise Solution


Please share your code or answers with your classmates for the Day 16 Code Exercise and related Notebook Activity questions.

Share code using


Only use code or watch video solution if you’re unsure how to solve or get stuck. It’s better to attempt writing the code first.

[Swift 1] Day 16 - Saving and Loading with NSCoding Protocol using the NSKeyedArchiver

Hi, Paul

I just went through your example.
You are just using one extra class: Item correct ?
I was trying to use the Inventory class as well, but I am having problems adding my item to it.
What I am trying is:


I have ‘newItem’ which is not nil, but I get a nil error when trying to add this to the array within Inventory, so I guess there is something wrong logically with my code.


When do you create itemArray? It sounds like you didn’t’ initialize the array before using it.

Any more code samples to look at?



Hi, Paul

here is my code:

I didn’t use the Inventory as of now, I think there is a problem with appending the custom class to the array inside the other custom class. I was trying to figure it out and it seemed as you need to convert it to NSObject first.


Please use only in portrait mode ;)))


Merry Xmas ! :))
Just wanted to ask one more thing - is there a better way to handle multiple value validations ?
Let’s say if I have a form with 20 different values and I want to make sure they are all filled out correctly and I want a specific error message depending on the one that is wrong/missing. If I use ‘if else’ statements it becomes a little ugly to say the least…

something like :

if let text1 = text1Field.text { continue } else { abort, error = “blabla bla” }
if let text2 = text2Field.text { continue } else { abort, error = “missing blaaa” }
if let text3 = text3Field.text { continue } else { abort, error = “asdsdd” }

Or maybe there is a specific way for making forms ?



What code didn’t work with saving the inventory?

You shouldn’t have to convert to NSObject to add items to an array that has a type of Item.

Un-archiving may force you to convert between AnyObject? and Item.

Any more details on the exact issue?


Any way you do it, the validation code is going to get messy.

There isn’t anything special that you can do.

One approach would be to test all the values, another way is to nest everything.

if x != nil && y != nil && z != nil {
// valid input


Ok, thanks, Paul!
I was able to finish that up, pretty much how I wanted :smile:
The only thing that I left out is deleting contacts, but that wouldn’t be a problem.

Here is the updated app:


Hi here is my version. I spent ages doing it for myself and couldn’t get it to work. I think it was following the file with the items all over the place.
My version has the image for the photo, checks the email, can go forward and backwards, loads, saves and has a message output for errors.

Github page for the app



I am currently on the videos and trying to get the example working. My problem is that I can first start the app and save inventory, however, when I restart the app, I get an “unrecognized selector sent to instance”. Using the automatic breakpoint feature, I was able to isolate the error to the loading function:


 func loadInventory(fromPath path: String) -> Inventory? {

    var result: Inventory? = nil

    result = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as! Inventory?
    print("result from loadInventory: \(result)")

    return result

It seems like that the it has trouble loading the inventory. I have tried to take out the plist extension but to no avail.

It would be great if @PaulSolt could take a look :slightly_smiling:




Hi all,

I have figured it out by comparing all files with filemerge to @PaulSolt final project files. I forgot to add the NSCoding protocol to the Inventory class as well as wrote:

required init?(code decoder: NSCoder)

instead of:

required init?(coder decoder: NSCoder)

However, this brings me to the more interesting question, how can you efficiently debug errors with the NSCoding protocol since the error message “unrecognized selector sent to instance” was not really helpful. Particularly, since the inventory.plist file was created and look exactly as it should be.




unrecognized selector sent to instance is a clue that your method name is incorrect. Method names have been called selectors in Objective-C, which is where that name comes from.

You should be able to look at the error message and it should say which selector it is trying to call. Read it carefully, and that will give you a clue something is wrong with what you’re trying to do for that method.

Decoder is all about reading and unarchiving. That step will fail if your plumbing isn’t hooked up, so you just need to double check that you can open a file. This isn’t the writing step (which generated the inventory.plist file).

When I do file input/output (i/o). I’m always building up… first writing, then working on reading. Both operations need to work hand-in-hand. And on more complex projects you should get into writing a unit test that could test if those steps do work… so that you don’t accidentally break something when you go to ship your app.

Better Debugging?

You will get better with time and exposure to new code. The more you experiment the better. You could try redoing this app from scratch to re-inforce the concepts that you learned. Or something similar using a different set of data.

Compile Time Errors

When I change the “coder” to “code” in the Inventory I get a compile time error, did you not see that?

InvetoryTracker2/inventory.swift:11:7: Type 'Inventory' does not conform to protocol 'NSCoding'

Auto Complete

Using Auto Complete to generate these methods will also help, instead of typing them by hand. Type “init” and press ESC to get a list of methods and choose the correct one. Do the same for the encoder, type “encode” and press ESC to choose the correct method.

For most delegate protocols (NSCoding) you can look at the documentation, start typing the first few letters and then use Auto Complete to fill out the proper name.