How to Cast from Uint16 to Nsnumber

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 to
NSString, 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



Leave a reply



Submit