Reputation: 473
I am scanning for BlueTooth devices. I want to log them in an array of strings. I want to be able to save them but get the following errors:
Could not cast value of type 'CBUUID' (0x1f2760918) to 'NSString' (0x1f26a42d0).
CoreBT[9728:3053605] Could not cast value of type 'CBUUID' (0x1f2760918) to 'NSString' (0x1f26a42d0).
I have the following code below. There is no reference to an array as I can't even get it to a string.
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
print("peripheral Name: \(peripheralName)")
let uniqueID = (advertisementData["kCBAdvDataServiceUUIDs"] as! NSArray).firstObject! as! String
// The above line produces an error
//Removing as! String will work prevent error but still cannot get from "any" to "string"
let x = advertisementData
print("x: \(x)")
let y = advertisementData["kCBAdvDataServiceUUIDs"]
print("y: \(y)")
print("uniqueID: \(uniqueID)")
self.UIDCountNumber = UIDCountNumber + 1
self.UID_Count.text = String(self.UIDCountNumber)//label counting devices
self.last_UID.text = uniqueID as? String //Label is not changing
}
}
Any thoughts on getting these as strings so I can store them in an array?
Upvotes: 2
Views: 4678
Reputation: 6982
The line
let uniqueID = (advertisementData["kCBAdvDataServiceUUIDs"] as! NSArray).firstObject! as! String
produces a crash because the UUID is not of String
type but of completely unrelated CBUUID
type. You can extract UUID string from CBUUID
like so
guard let uuids = advertisementData["kCBAdvDataServiceUUIDs"] as? [CBUUID] else { return }
guard let uniqueID = uuids.first?.uuidString else { return }
Also, give up force cast operator - as!
. This is a really bad practice. Use guard
statements or optional chaining
Upvotes: 6
Reputation: 54706
The issue is that the Service UUIDs are of type CBUUID
, so you should cast to [CBUUID]
instead of NSArray<String>
. Btw it's a better idea to use the CB...Key
constants instead of String literals when retrieving values from advertisementData
.
Once you have a single CBUUID
instance, you can use uuidString
to convert it to a String
and display it on a UILabel
.
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
print("peripheral Name: \(peripheralName)")
guard let uniqueIDs = advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID], let uniqueID = uniqueIDs.first else { return }
let x = advertisementData
print("x: \(x)")
let y = advertisementData["kCBAdvDataServiceUUIDs"]
print("y: \(y)")
print("uniqueID: \(uniqueID)")
self.UIDCountNumber = UIDCountNumber + 1
self.UID_Count.text = String(self.UIDCountNumber)//label counting devices
self.last_UID.text = uniqueID.uuidString
}
}
Unrelated to your issue, but you should also conform to the Swift naming convention, which is lowerCamelCase for variable names (uidCountNumber
, uidCount
and lastUID
).
Upvotes: 4
Reputation: 36612
Apple provides an API for getting the string:
https://developer.apple.com/documentation/corebluetooth/cbuuid/1518742-uuidstring
var uuidString: String { get }
Upvotes: 6