Cant search for custom CBUUID

Viewed 2283

I have an app that works (so far so good) in connecting my iOS device to a bluetooth arduino, as of now this has been mostly for practice, but now I received the real thing that I'm supposed to connect to.
The problem is that I can't find it! (when I search for it). If I do scanwithservices: nil, I can see the device and connect to it. However if i scanwithservices: [device'sCBUUID] then I don't get anything. I double/triple/quatrupled checked the CBUUID using other apps, using my own app and looking at the device documentation, however no matter what I can't find it.
It has a custom CBUUID, from what I've read that's not standard, the CBUUID is:

BLETPodService = CBUUID(string: "4D494B45-414c-5741-5953-524F434B5321")

Searching for this yields nothing, however if I scan for nil I find it and if i check it's characteristics using the Bluefruit app (from Adafruit) I can see it's services and characteristics ID and they match that string I posted in here!
I told a friend and he said it's a BLE bug thats been there for ages (regarding custom CBUUIDs), is this true? is there really no fix for this?

EDIT adding the full scanning code just FYI:

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        var statusMessage = ""

        switch (central.state)
        {
        case .unsupported:
            statusMessage = "Bluetooth Low Energy is not supported!"
            displayStatusAlert(localmsg: statusMessage)
            print(statusMessage)
        case .unauthorized:
            statusMessage = "Bluetooth Low Energy is not authorized!"
            displayStatusAlert(localmsg: statusMessage)
            print(statusMessage)
        case .unknown:
            statusMessage = "Bluetooth Low Energy is unknown!"
            displayStatusAlert(localmsg: statusMessage)
            print(statusMessage)
        case .poweredOff:
            statusMessage = "Bluetooth Low Energy is powered off!"
            displayStatusAlert(localmsg: statusMessage)
            print(statusMessage)
        case .resetting:
            statusMessage = "Bluetooth Low Energy is resetting!"
            displayStatusAlert(localmsg: statusMessage)
            print(statusMessage)
        case .poweredOn:
            statusMessage = "BLE is ready!" //If BLE is ready then start scanning right away!
            peripheralsFoundNames.removeAll()
            peripheralsFoundCB.removeAll()
            peripheralsFoundRSSIs.removeAll()
            peripheralsFoundData.removeAll() //Remove previous data from previous scans
            central.scanForPeripherals(withServices: nil, options: nil)
        }
    }

//What happens when you discover a peripheral
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        //What to do when it discovers a peripheral, add it to the array list
        print("Peripheral found: " + (peripheral.name ?? "Unknown Name"))
        peripheralsFoundNames.append((peripheral.name ?? "Unknown Name"))
        peripheralsFoundData.append((advertisementData.description ))
        peripheralsFoundCB.append(peripheral)
        peripheralsFoundRSSIs.append(RSSI)
    }
4 Answers

I happen to be working on both BLE firmware and iOS App at the same time. I had the same issue that the filter not working.

The reason that iOS couldn't find the device with the UUID is that the device doesn't include the UUID when it is advertising.

I had to change the device firmware to add service UUID in the advertising data packet. With device advertising the UUID, UUID filter worked as expected.

I also had this problem, but I've found some tricky way.

You can try to match UUIDs (string value) directly in didDiscoverPeripheral func:

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
  if let services = peripheral.services {
        for service in services {
            if service.uuid.uuidString.lowercased() == "4D494B45-414c-5741-5953-524F434B5321".lowercased() {
              if !peripheralsFoundCB.contains(peripheral) {
                   peripheralsFoundCB.append(peripheral)
              }
            }
        }
    }
}

If this way doesn't work for you I have one more:

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
    peripheral.discoverServices(nil)
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
     if let services = peripheral.services {
        for service in services {
            if service.uuid.uuidString.lowercased() == "4D494B45-414c-5741-5953-524F434B5321".lowercased() {
              if !peripheralsFoundCB.contains(peripheral) {
                   peripheralsFoundCB.append(periphera
              }
            }
        }
    }
}

Of course you should use

scanwithservices: nil

Swift 3:

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {

    self.selectPeripheral.discoverServices(nil)
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {

   let services = peripheral.services as [CBService]!{

        for service in services{

            if service.uuid.uuidString == "4D494B45-414c-5741-5953-524F434B5321"{
               print("service found")
            }
        }
   }
 }
Related