Swift: The Curious Case of NSDecimalNumber

It’s crazy how much I’m used to Swift failable initializers already. Just yesterday I was working with NSDecimalNumber, when I encountered the following scenario:

let numberText = "THIS IS NOT A NUMBER"

let myDecimalNumber = NSDecimalNumber(string: numberText)

By default, I expected myDecimalNumber to be nil. To my surprise, NSDecimalNumber does get initialized, but instead of a valid number it becomes “not a number”. No joke here, try this in a Playground!

The NSDecimalNumber API even has a +notANumber factory initializer! So if you need to check that your number is valid, you have to check your number against notANumber:

let numberText = "THIS IS NOT A NUMBER"

let myDecimalNumber = NSDecimalNumber(string: numberText)

if myDecimalNumber == NSDecimalNumber.notANumber() {
    println("This is not a valid number")
} else {
    println("my decimal number \(myDecimalNumber) is valid!")
}

// console output: "This is not a valid number"

The reason I’ve been enjoying Swift optionals and now failable initializers so much is because it makes it so easy to make architectural decisions in my own code.

Just think of how much the team who created the NSDecimalNumber API had to talk about the “notANumber” scenario. Today, if they were to write NSDecimalNumber from scratch, this would be a quick and easy decision with absolutely no argument – just make it a failable initializer, done!

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.