0

I have a ble app that provides a paired button. When the button is clicked, the app will scan for some ble devices with specific name and show them to a tableview. Below is the scan function:

func scan() {
    let bonding = userDefaults.bool(forKey: UserDefaultsKey.BONDING)
    if bonding {
        let serviceCount = userDefaults.integer(forKey: UserDefaultsKey.SERVICE_COUNT)
        var cbuuids = [CBUUID]()
        for i in 0..<serviceCount {
            if let serviceString = userDefaults.string(forKey: "SERVICE\(i)") {
                print("[BLEManager] SERVICE\(i): \(serviceString)")
                cbuuids.append(CBUUID(string: serviceString))
            }
        }
        centralManager.scanForPeripherals(withServices: temp, options: nil)
    } else {
        centralManager.scanForPeripherals(withServices: nil, options: nil)
    }
}

When a ble device is chosen, the app will connect to it and save its services using UserDefaults:

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
    guard error == nil else{
        print("ERROR: \(#file, #function)")
        return
    }
    var index = 0
    for service in peripheral.services!{
        connectPeripheral.discoverCharacteristics(nil, for: service)
        userDefaults.set(service.uuid.uuidString, forKey: "SERVICE\(index)")
        index = index + 1
    }
    userDefaults.set(index, forKey: UserDefaultsKey.SERVICE_COUNT)
    userDefaults.set(true, forKey: UserDefaultsKey.BONDING)
}    

Everything works perfectly for the first time when all the UserDeaults things doesn't exist yet. But after I disconnected and restart my app and press the same paired button again, which makes my centralManager scans for the peripheral with previously stored services, nothing happens. I expected that the ble device connected previously should show on the tableview. Does this mean that I can't paired to specific device using this way?

Tony Chen
  • 207
  • 2
  • 13
  • 1
    Be careful using word: Pairing in Bluetooth is a specific term and you don't see to do so. Also it's not because a peripheral has services that it advertise them.If you don't see them in `centralManager(_:didDiscover:advertisementData:rssi:)`, it won't work. Also, I don't remember, but if you have 2 devices with 2 differences services, I think that the scan with services is an AND not an OR, so a device has to advertise both services to be discovered (info to check). – Larme Jun 29 '18 at 21:06

1 Answers1

1

I think you want to pass "var cbuuids" (your previously scanned UUIDs) to scanForPeripherals.

centralManager.scanForPeripherals(withServices: cbuuids, options: nil)

You are currently passing "temp". My guess is that it is not the right UUID.

Kentaro Okuda
  • 1,557
  • 2
  • 12
  • 16