Reputation: 61646
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
Upvotes: 3
Views: 2588
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