Just like the title says. I had to store Int64
in NSUserDefaults
and the only way I found to do that was storing it as NSNumber
like
NSNumber(longLong: someInt64)
but I don't know how to convert it back to Int64.
TL;DR
Use the int64Value
property of NSNumber
to retrieve the Int64
value:
let someInt64: Int64 = 314
let n = NSNumber(value: someInt64)
let m = n.int64Value // m is an `Int64`
Long Answer
NSNumber
is unlike primitive types such as Int
and Double
. NSNumber
is a class that comes from Foundation, which was designed around Objective-C and its limitations. NSNumber
serves as an object wrapper for primitive types (such as Int
, Double
, and Bool
) which are not objects.
In Objective-C, objects are stored in NSArray
and NSDictionary
, but these can only hold objects (i.e. instances of classes). Primitive types such as Int
, Double
, and Bool
are not objects. The designers of Objective-C had a problem; it wouldn't be very useful if you couldn't put integers or doubles in arrays and dictionaries. The solution was to wrap these primitive types in a class called NSNumber
.
Originally in Objective-C, NSNumbers
were created with constructors such as:
// Objective-C
NSNumber *n = [NSNumber numberWithDouble: 3.14];
NSNumber *b = [NSNumber numberWithBool: YES];
When Modern Objective-C features were added, it became possible to create them more simply:
// Modern Objective-C
NSNumber *n = @3.14;
NSNumber *b = @YES;
Once you have an NSNumber
, you can extract the contained value by calling the appropriate property:
// Objective-C
double d = [n doubleValue]; // method call notation
double d = n.doubleValue; // dot notation
// Swift
let d = n.doubleValue
Swift has the ability of creating NSNumber
on the fly when assigning a primitive type (Int
, Double
, Bool
, etc.) to a variable of type NSNumber
. This was done to make it easy to call Cocoa
and Cocoa Touch
APIs from Swift without having to explicitly wrap primitive types (which would have been painful).
// In Swift
let n: NSNumber = 3.14 // No need to do let n = NSNumber(double: 3.14)
let a = NSMutableArray()
a.addObject(3.14) // No need for a.addObject(NSNumber(double: 3.14))
a.addObject(true) // No need for a.addObject(NSNumber(bool: true))
The weird thing about NSNumber
is that you can put in one type and retrieve another:
// In Swift
let n: NSNumber = 3.14
let truth = n.boolValue
print(truth) // "true"
so it is up to the program to keep track of what is in there.
So, if you have an NSNumber
and want the value contained within as an Int64
, you need to access it with the int64Value
property:
let n = NSNumber(value: someInt64)
let m = n.int64Value // m is an `Int64`
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With