How to cast from UInt16 to NSNumber
var castAsNSNumber = NSNumber(unsignedShort: myUInt16)
Objective C convert number to NSNumber
In a sort of symmetry with your earlier question, NSNumber
is an object type. You need to create it via a method invocation such as:
[p setAge:[NSNumber numberWithInt:10]];
Your current code is attempting simply to cast the arbitrary integer 10
to a pointer. Never do this: if the compiler didn't warn you about it, you would then be trying to access some completely inappropriate bytes at memory location 10
as if they were an NSNumber
object, which they wouldn't be. Doing that stuff leads to tears.
Oh, and just to preempt the next obvious issues, remember that if you want to use the value in an NSNumber
object, you need to get at that via method calls too, eg:
if ( [[p age] intValue] < 18 )
...
(NSNumber
is immutable, and I think it is implemented such that identical values are mapped to the same object. So it is probably possible to get away with direct pointer comparisons for value equality between NSNumber
objects. But please don't, because that would be an inappropriate reliance on an implementation detail. Use isEqual
instead.)
How to convert/cast NSNumber 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`
Swift casts Bool to NSNumber using 'as' operator
The as
operator can be used for two types of casting. Type casting and bridge casting. Type casting can be used to convert subclasses to superclasses (called upcasting) or to downcast superclasses to subclasses (only works if first the subclass instance was upcasted). This is what you see in your example with the Any
array.
Bridge casting is however a mechanisms provided for easier interoperability between Foundation
and Swift
classes. NSNumber
has an init
method that takes a Bool
as its input argument. The as
operator in your example calls this initializer, so
var b: Bool = true
var n: NSNumber = b as NSNumber
is just a shorthand notation for
var b:Bool = true
var n = NSNumber(value: b)
Int
and Bool
are both Swift
types, so bridge casting doesn't work on them.
For more information, check the documentation of NSNumber.
Working with NSNumber & Integer values in Swift 3
Before Swift 3, many types were automatically "bridged" to an
instance of some NSObject
subclass where necessary, such as String
toNSString
, or Int
, Float
, ... to NSNumber
.
As of Swift 3 you have to make that conversion explicit:
var currentIndex = 0
for item in self.selectedFolder.arrayOfTasks {
item.index = currentIndex as NSNumber // <--
currentIndex += 1
}
Alternatively, use the option "Use scalar properties for primitive data types" when creating the NSManagedObject
subclass,
then the property has some integer type instead of NSNumber
,
so that you can get and set it without conversion.
Convert CBUUID to NSNumber in swift
As per [the documentation[(https://developer.apple.com/documentation/corebluetooth/cbadvertisementdataservicedatakey), the dictionary associated with CBAdvertisementDataServiceDataKey
is of type <CBUUID,Data>
. Having retrieved the dictionary you can then subscript it using the appropriate CBUUID
instance (0x180A is the Device Information service).
public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
guard peripheral.state != .connected else {
return
}
if let deviceInformation = advertisementData[CBAdvertisementDataServiceDataKey] as? Dictionary<CBUUID,Data>,
let data = deviceInformation[CBUUID(string:"0x180A")] {
// Do something with the data
}
}
Related Topics
Loading Multiple Google Interstitial Ads Makes App Crash
Anchoring Multiple Scenes in Realitykit
How to Replace the Values of Labels in iOS-Charts
Appdelegate Segue Alternative Pass Data
Read and Write CSV Files in Swift 3
Provide Simple Method to Get Current Speed (Implementing Speedometer)
Get All Available Characters from a Font
Firebase and Reading Nested Data Using Swift
How to Convert a Computed Value to a Literal for Enum Initialization
Change Notification from Observable Object as a Nested Object in Swiftui
Function Builder Not Working When Only One Value
How to Access Content View's Elements Later in Swiftui
iOS 13.1 Cannot Save File to App Directory
Resulting Mtltexture Lighter Than Cgimage
How to Add a Move Back to User Location Button in Swiftui
How to Use Multiple Mtlrenderpipelinestates in One Mtlrendercommandencoder