validateRaise Function Changes in Swift 3 (Exception is not being handled)

I have recently taken up this book in order to get more familiar with Swift as of Swift 3. I understand that the language is currently in beta, but I still wanted to get used to Swift 3’s syntax rather than Swift 2 since so much has changed (and now, to my eyes, seems like a much more functional and stable language than it did in the past couple of years).

I’ve been able to complete every exercise/example so far, however on this validateRaise() function I am unable to determine a solution–I am still receiving the exception we are supposed to be handling with that very vunction for setting a value to nil after implementing the changes for Swift 3.

Here’s my code (copy/pasted from the github source, minor changes for Swift 3):

func validateRaise(raiseNumberPointer: AutoreleasingUnsafeMutablePointer<NSNumber?>) throws {
    let raiseNumber = raiseNumberPointer.pointee // "memory" is now "pointee" in Swift 3
    if raiseNumber == nil {
        let domain = "UserInputValidationErrorDomain"
        let code = 0
        let userInfo = [NSLocalizedDescriptionKey : "An employee's raise must be a number."]
        throw NSError(domain: domain, code: code, userInfo: userInfo)
    }
}

I don’t believe that this function is even being called. I set a breakpoint at the function level and nothing happens when I set the value of the raise to be empty (the exception is still raised in the console). I have:

  • Validated that the right table view cell is being validated
  • Checked to ensure that my code is as close to the source as possible (resorted to copy/pasting, still didn’t help)
  • Checked Swift docs for how to implement this function (all I could find were Objective-C explanations, which don’t really help)

Here’s to hoping that someone can help me out with this!

Thanks,

Figured it out! Posting an update so that maybe BNR notices and provides updates (and for people going along with Swift 3)

The method signature has been totally revamped to pretty much eliminate user-error. You must override the function validateValue(_ ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?>, forKey inKey: String) and replace it with the contents as follows:

override func validateValue(_ ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?>, forKey inKey: String) throws {
    let raiseNumber = ioValue.pointee // "memory" is now "pointee" in Swift 3
    if inKey == "raise" && raiseNumber == nil {
        let domain = "UserInputValidationErrorDomain"
        let code = 0
        let userInfo = [NSLocalizedDescriptionKey : "An employee's raise must be a number."]
        throw NSError(domain: domain, code: code, userInfo: userInfo)
    }
}

This is actually pretty neat because not only do you have the autocomplete to keep you from messing up the method declaration, you can now handle multiple key values in one function and throw errors accordingly. Hopefully this is useful to someone!

3 Likes

It was (useful)! I’ve also been going through the book using Swift 3, and this tripped me up, too—which is why I went here looking for a solution. Thanks!

it doesn’t look better?


if inKey == “raise” && (ioValue.pointee == nil) {

Thanks for the fix - I could have spent many hours rather 60 seconds without this clue!

I just started getting hung up on this one. Thanks for the solution!

I just started on this exercise and it appears that the validateValue function is never being called. I’ve inserted a print statement at the beginning of the function implementation and it is never executed. All the right boxes are checked and the spelling is correct. This is a tough one.

I went back and reimplemented everything. When I reread the instructions I found what I was doing wrong. It all works fine. Thanks to all for providing the above guidance.