AngryHacker
AngryHacker

Reputation: 61646

How do I convert a optional NSInteger to a non-optional one?

I need to retrieve a setting (with Swift):

var highScoreNumber: NSInteger = 0
var returnValue: [NSInteger]? = NSUserDefaults.standardUserDefaults().objectForKey("food") as? [NSInteger]

if (returnValue != nil) {
    highScoreNumber = returnValue as NSInteger
}

I tried this and other variations of the code and I always get

'NSInteger?' not convertible to 'NSInteger'

This is my first foray into Swift, so

  1. Am I missing something simple in the conversion?
  2. Is there a better way to retrieve an NSInteger from settings?

Upvotes: 3

Views: 2588

Answers (1)

Airspeed Velocity
Airspeed Velocity

Reputation: 40973

When converting a nullable value to a non-nullable one, there are many good options to choose from.

But in your case, you have two issues. One is the array you’re fetching from NSUserDefaults is an array of integers, so you need to decide which one you want from that array.

If it’s the first one you want, you can use the first property. You can use optional chaining to get it. And since it’s a high score, you probably want to default to zero if it’s not present.

Here’s that in one line:

let returnValue = NSUserDefaults.standardUserDefaults().objectForKey("food") as? [Int]

let highscore = returnValue?.first ?? 0

Things to note about the above: there’s no need to give the type to the left of the = if the type is unambiguously determined by what lies to the right of the =. And it’s better to prefer Int over NSInteger.

The returnValue?.first says “if returnValue is nil, then nil, else the value of first (which, itself, returns nil if the array is empty).” The ?? says “if the left of ?? is nil, then the value on the right of nil, else the unwrapped value from the left”.

That said – do you really mean to store an array? Or do you really just want to store a single integer in the defaults and then get that out directly?

let highscore = NSUserDefaults.standardUserDefaults().integerForKey("food")
// and elsewhere in your code, when saving
NSUserDefaults.standardUserDefaults().setInteger(highscore, forKey: "food")

(integerForKey already returns a 0 default when not present rather than an optional, so no need for any unwrapping)

Upvotes: 5

Related Questions