I am trying to write a simple app that constantly broadcasts a 'beacon' even when the app is not active. I know that using CoreLocation will switch this off when the app is not in use so I was trying to build a solution using Core Bluetooth.
The trouble is that I can't get the app to start advertising.
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralManagerDelegate {
var centralManager:CBCentralManager = CBCentralManager()
var peripheralManager:CBPeripheralManager = CBPeripheralManager()
let uuid:CBUUID = CBUUID(string: "DCEF54A2-31EB-467F-AF8E-350FB641C97B")
override func viewDidLoad() {
super.viewDidLoad()
self.peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
self.centralManager.delegate = self
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: uuid]
peripheralManager.startAdvertising(advertisingData)
centralManager.scanForPeripheralsWithServices([uuid], options: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func peripheralManagerDidStartAdvertising(peripheral: CBPeripheralManager, error: NSError?) {
print("started advertising")
print(peripheral)
}
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
print("peripheral discovered")
print("peripheral: \(peripheral)")
print("RSSI: \(RSSI)")
}
func centralManagerDidUpdateState(central: CBCentralManager) {
print("central state updated")
print(central.description)
if central.state == .PoweredOff {
print("bluetooth is off")
}
if central.state == .PoweredOn {
print("bluetooth is on")
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: uuid]
let service = CBMutableService(type: uuid, primary: true)
self.peripheralManager.addService(service)
peripheralManager.startAdvertising(advertisingData)
centralManager.scanForPeripheralsWithServices(nil, options: nil)
}
if central.state == .Unsupported {
print("bluetooth is unsupported on this device")
}
}
func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager) {
print("peripheral state updated")
print("\(peripheral.description)")
}
}
I have installed this on two devices, the issue seems to be in the transmission of the advert since peripheralManagerDidStartAdvertising() is never called.
The issue is related to immediate call .startAdvertising() right after .addService() call.
You must call .startAdvertising() ONLY after func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) delegate method is called.
If you use this init method the centralManagerDidUpdateState is going to work. You can set the CBCentralManagerScanOptionAllowDuplicatesKey option if you would like to see the beacons continually.
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralManagerDelegate {
var centralManager:CBCentralManager!
var peripheralManager:CBPeripheralManager = CBPeripheralManager()
let uuid:CBUUID = CBUUID(string: "DCEF54A2-31EB-467F-AF8E-350FB641C97B")
override func viewDidLoad() {
super.viewDidLoad()
self.peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
self.centralManager = CBCentralManager(delegate: self, queue: nil)
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: uuid]
peripheralManager.startAdvertising(advertisingData)
centralManager.scanForPeripheralsWithServices([uuid], options: [ CBCentralManagerScanOptionAllowDuplicatesKey : true])
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func peripheralManagerDidStartAdvertising(peripheral: CBPeripheralManager, error: NSError?) {
print("started advertising")
print(peripheral)
}
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
print("peripheral discovered")
print("peripheral: \(peripheral)")
print("advertisement: \(advertisementData)")
if let data = advertisementData["kCBAdvDataServiceData"] {
print("found advert data: \(data)")
}
print("RSSI: \(RSSI)")
}
func startAdvert(){
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: uuid]
peripheralManager.startAdvertising(advertisingData)
}
func centralManager(central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: NSError?) {
print("peripheral disconnected")
print("peripheral: \(peripheral)")
}
func centralManagerDidUpdateState(central: CBCentralManager) {
print("central state updated")
print(central.description)
if central.state == .PoweredOff {
print("bluetooth is off")
}
if central.state == .PoweredOn {
print("bluetooth is on")
centralManager.scanForPeripheralsWithServices(nil, options: [ CBCentralManagerScanOptionAllowDuplicatesKey : true])
startAdvert()
}
if central.state == .Unsupported {
print("bluetooth is unsupported on this device")
}
}
func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager) {
print("peripheral state updated")
print("\(peripheral.description)")
}
}
The CBAdvertisementDataServiceUUIDsKey value passed to startAdvertising should be an array of CBUUID objects but you are passing a single CBUUID
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: [uuid]]
Related
I found the received signal strength of iPhone to the bluetooth 4.0 module that I am using, but it is in the format of NSNumber and the writeValue() method only takes values of type Data.
How would I go about converting from NSNumber to type Data? Or is there another, better way to send this data from my iPhone to the bluetooth module?
The bluetooth module I am using is the HM-10 and it is connected to an arduino.
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBPeripheralDelegate, CBCentralManagerDelegate {
private var centralManager: CBCentralManager!
private var peripheral: CBPeripheral!
var readRSSITimer: Timer!
func centralManagerDidUpdateState(_ central: CBCentralManager) {
print("Central state update")
if central.state != .poweredOn {
print("Central is not powered on")
} else {
print("Central scanning for", ParticlePeripheral.particleLEDServiceUUID);
centralManager.scanForPeripherals(withServices: [ParticlePeripheral.particleLEDServiceUUID],
options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])
}
}
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
// We've found it so stop scan
self.centralManager.stopScan()
// Copy the peripheral instance
self.peripheral = peripheral
self.peripheral.delegate = self
// Connect!
self.centralManager.connect(self.peripheral, options: nil)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
if peripheral == self.peripheral {
print("Connected to your Particle Board")
peripheral.discoverServices([ParticlePeripheral.particleLEDServiceUUID])
print(self.peripheral.readRSSI())
self.startReadRSSI()
peripheral.delegate = self
}
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
self.stopReadRSSI()
if self.peripheral != nil {
self.peripheral.delegate = nil
self.peripheral = nil
}
}
func stopScan() {
self.centralManager.stopScan()
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if let services = peripheral.services {
for service in services {
if service.uuid == ParticlePeripheral.particleLEDServiceUUID {
print("LED service found")
//Now kick off discovery of characteristics
peripheral.discoverCharacteristics([ParticlePeripheral.redLEDCharacteristicUUID,
], for: service) //edited this
return
}
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if let characteristics = service.characteristics {
for characteristic in characteristics {
if characteristic.uuid == ParticlePeripheral.redLEDCharacteristicUUID {
print("Red LED characteristic found")
} else if characteristic.uuid == ParticlePeripheral.greenLEDCharacteristicUUID {
print("Green LED characteristic found")
} else if characteristic.uuid == ParticlePeripheral.blueLEDCharacteristicUUID {
print("Blue LED characteristic found");
}
}
}
}
func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
print("RSSI = \(RSSI)")
}
#objc func readRSSI() {
if (self.peripheral != nil) {
self.peripheral.delegate = self
print("RSSI Request - \(peripheral.name!)")
print(self.peripheral.readRSSI())
} else {
print("peripheral = nil")
}
}
func startReadRSSI() {
if self.readRSSITimer == nil {
self.readRSSITimer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(ViewController.readRSSI), userInfo: nil, repeats: true)
}
}
func stopReadRSSI() {
if (self.readRSSITimer != nil) {
self.readRSSITimer.invalidate()
self.readRSSITimer = nil
}
}
}
You can use Data bytes initialiser and pass your received number to it to convert it to Data:
init(bytes: UnsafeRawPointer, count: Int)
extension NSNumber {
var data: Data {
var source = self
return Data(bytes: &source, count: MemoryLayout<NSNumber>.size)
}
}
To convert it from Data back to NSNumber you can use Data's method
func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType
extension Data {
func object<T>() -> T { withUnsafeBytes { $0.load(as: T.self) } }
var nsNumber: NSNumber { object() }
}
Playground testing:
let integerNumber = NSNumber.init(value: 2)
let integerNumberData = integerNumber.data
let loadedintegerNumber: NSNumber = integerNumberData.nsNumber
loadedintegerNumber // 2
let floatNumber = NSNumber.init(value: 2.7)
let floatNumberData = floatNumber.data
let loadedFloatNumber: NSNumber = floatNumberData.nsNumber
loadedFloatNumber // 2.7
let boolNumber = NSNumber.init(value: true)
let boolNumberData = boolNumber.data
let loadedBoolNumber: NSNumber = boolNumberData.nsNumber
loadedBoolNumber // 1
Until now the iPhone has paired to a bluetooth device when the app is opened, but I want to pair with a button click instead. I tried to put all the scanning and connection functions in a IBAction, but nothing happens when I push the button. In the first function after the IBAction I have a print output to check if it even enters the function, but I don't get the print. I also tried to put a delay after the manager.scanForPeripherals but didn't work either. What am I missing here? anyone know?
Thanks for any replies! here is my code (without the delay):
var manager: CBCentralManager!
var device: CBPeripheral?
var characteristics: [CBCharacteristic]?
var serviceUUID = "1234"
var char1 = "FFE1"
let deviceName = "HMSoft"
var connected = CBPeripheralState.connected
var disconnected = CBPeripheralState.disconnected
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
manager = CBCentralManager(delegate: self, queue: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn: break
// manager.scanForPeripherals(withServices: nil, options: nil)
case .unknown: break
case .resetting: break
case .unsupported: break
case .unauthorized: break
case .poweredOff:
break
}
}
#IBAction func connectBluetooth(_ sender: Any) {
manager.scanForPeripherals(withServices: nil, options: nil)
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
if peripheralName == self.deviceName {
// save a reference to the sensor tag
self.device = peripheral
self.device!.delegate = self
// Request a connection to the peripheral
self.manager.connect(self.device!, options: nil)
print("Check")
}
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.discoverServices(nil)
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if error != nil {
return
}
if let services = peripheral.services {
for service in services {
if (service.uuid == CBUUID(string: serviceUUID)) {
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
device = peripheral
characteristics = service.characteristics
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
if error != nil {
return
}
}
}
When you initialise the CBCentralManager and set its delegate, the delegate will start receiving events.
So, if you only want the CBCentralManager to be active once the user has tapped a button, rather than as soon as the screen loads, the minimum you have to do is move the code that initialises the manager from viewDidLoad to the button action.
So:
Move manager = CBCentralManager(delegate: self, queue: nil) from viewDidLoad to #IBAction func connectBluetooth(_ sender: Any),
Remove the call to scanForPeripherals from the IBAction, and;
Uncomment // manager.scanForPeripherals(withServices: nil, options: nil) in centralManagerDidUpdateState.
Don't put the function func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) inside the button.
Try instead this:
#IBAction func connectBluetooth(_ sender: Any) {
manager = CBCentralManager(delegate: self, queue: nil)
manager.scanForPeripherals(withServices: nil, options: nil)
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
if peripheralName == self.deviceName {
// save a reference to the sensor tag
self.device = peripheral
self.device!.delegate = self
// Request a connection to the peripheral
self.manager.connect(self.device!, options: nil)
print("Check")
}
}
}
It's quite important that the device know that BLE is on before you can scan.
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch (central.state) {
case .unsupported:
print("BLE is unsupported")
case .unauthorized:
print("BLE is unauthorized")
case .unknown:
print("BLE is unknown")
case .resetting:
print("BLE is reseting")
case .poweredOff:
print("BLE is powered off")
case .poweredOn:
print("BLE is powered on")
//must be called
}
}
I'm coding BLE test apps for iOS with Swift 3 and I'm struggling with a problem that I can't scan devices.
I want to call the method "print("devicename: \(peripheral)")" at the last block.
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate {
private var isScanning = false
var centralManager: CBCentralManager!
override func viewDidLoad() {
super.viewDidLoad()
self.centralManager = CBCentralManager(delegate: self,queue: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == CBManagerState.poweredOn {
centralManager.scanForPeripherals(withServices: nil,options: nil)
} else {
print("not ready")
}
}
private func centralManager(central: CBCentralManager!,didDiscoverPeripheral peripheral: CBPeripheral!,advertisementData: [String : AnyObject]!,RSSI: NSNumber!)
{
print("devicename: \(peripheral)")
}
}
func centralManagerDidUpdateState(_ central: CBCentralManager){
switch central.state {
case .poweredOn: central.scanForPeripherals(withServices: nil, options: nil)
default: print("Please turn on bluetooth")
break
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
print("----->",advertisementData)
print("==>", peripheral)
}
I am trying to connect automatically to my AirPods with a simple app using BLE. I get the name of the device and the status to "connecting", but for some reason I can't connect to it. Function 'didConnect peripheral' is never triggered.
I tried all different approaches from tutorials and from other posts, tried to store the peripheral data in an array to keep the reference but nothing seem to work.
Is there any step which I can get some extra info between 'didDiscover' and 'didConnect'?
Working in XCode 9.2, using Swift 4 and iOS 11.2 on iPhone.
Here's my code:
let deviceName = "AirPods de Roger"
var isConnected = false
var manager: CBCentralManager!
var peripheralBLE: CBPeripheral?
override func viewDidLoad() {
super.viewDidLoad()
manager = CBCentralManager(delegate: self, queue: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch manager.state {
case.poweredOff:
print("BLE service is powered off")
case.poweredOn:
print("BLE service is powered on and scanning")
manager.scanForPeripherals(withServices: nil, options: nil)
default:
print("BLE service in another state")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if peripheral.name == deviceName && isConnected == false {
self.manager.stopScan()
self.peripheralBLE = peripheral
self.peripheralBLE?.delegate = self
manager.connect(peripheral, options: nil)
isConnected = true
print("\(peripheral.name) pre-connected")
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
lblConnected.isHidden = false
print("AirPods Connected")
peripheral.discoverServices(nil)
}
This one is my current implementation:
import UIKit
import CoreBluetooth
var manager: CBCentralManager!
var peripheralBLE: CBPeripheral!
class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
let deviceName = "AirPods de Iván"
var isConnected = false
#IBOutlet weak var Label: UILabel!
#IBAction func Click(_ sender: UIButton) {
self.connect()
}
override func viewDidLoad() {
super.viewDidLoad()
manager = CBCentralManager(delegate: self, queue: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func connect() {
manager.connect(peripheralBLE, options: nil)
print("connect")
self.updateLabelStatus()
}
func disconnect() {
manager.cancelPeripheralConnection(peripheralBLE!)
print("disconnect")
self.updateLabelStatus()
}
func updateLabelStatus() {
switch peripheralBLE.state {
case.connected:
Label.text = "connected"
case.disconnected:
Label.text = "disconnected"
case.connecting:
Label.text = "connecting"
case.disconnecting:
Label.text = "disconnecting"
default:
Label.text = "label"
}
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch manager.state {
case.poweredOff:
print("BLE service is powered off")
case.poweredOn:
print("BLE service is powered on and scanning")
manager.scanForPeripherals(withServices: nil, options: nil)
default:
print("BLE service in another state")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if peripheral.name == deviceName && isConnected == false {
print("found AirPods \(peripheral)")
peripheralBLE = peripheral
peripheralBLE!.delegate = self
manager.stopScan()
self.updateLabelStatus()
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("AirPods Connected")
peripheral.discoverServices(nil)
self.updateLabelStatus()
}
func centralManager(_ central: CBCentralManager,
didFailToConnect peripheral: CBPeripheral,
error: Error?) {
print("AirPods Connect error")
print(error)
self.updateLabelStatus()
}
}
I am finding the device but when I try to connect, nothing happens
BLE service is powered on and scanning
found AirPods <CBPeripheral: 0x1c4103f00, identifier = 0E6FCF72-B86E-FB10-DD62-4A575BAD0ECC, name = AirPods de Iván, state = disconnected>
connect
I can connect other devices with this code
I can connect the airpods with my mac without problems with a similar code
I can't connect airpods with my iphone :S
Something strange happens here I am almost sure that the code is right
Since the AirPods advertise with kCBAdvDataIsConnectable = 0, they're not supposed to be connected via BLE.
I'm creating a simple BLE app that communicates with a single peripheral. The phone acts as the central. I have an iPad which I'm using as the peripheral for testing. It has the app LightBlue installed to simulate a peripheral. The peripheral is supposed to send a string of data in this format.
TEM:25.11 | HUM:70 | PM10:43 | PM25:32
So I created a blank virtual peripheral in LightBlue with one service.
Below is my code for Bluetooth connectivity handling.
import UIKit
import CoreBluetooth
class ViewController: UIViewController {
fileprivate let serviceUUID = CBUUID(string: "19B10010-E8F2-537E-4F6C-D104768A1214")
fileprivate let characteristicUUID = CBUUID(string: "19B10011-E8F2-537E-4F6C-D104768A1214")
fileprivate var manager: CBCentralManager!
fileprivate var peripheral: CBPeripheral!
fileprivate var characteristic: CBCharacteristic!
override func viewDidLoad() {
super.viewDidLoad()
manager = CBCentralManager(delegate: self, queue: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
stopScan()
}
fileprivate func startScan() {
manager.scanForPeripherals(withServices: [serviceUUID], options: nil)
}
fileprivate func stopScan() {
manager.stopScan()
}
fileprivate func disconnectFromDevice() {
guard let peripheral = peripheral else { return }
manager.cancelPeripheralConnection(peripheral)
}
fileprivate func restoreCentralManager() {
manager.delegate = self
}
}
// MARK: - CBCentralManagerDelegate
extension ViewController: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unsupported:
print("Unsupported")
case .unauthorized:
print("Unauthorized")
case .poweredOn:
print("Powered On")
startScan()
case .resetting:
print("Resetting")
case .poweredOff:
print("Powered Off")
case .unknown:
print("Unknown")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print("Discovered \(String(describing: peripheral.name)) at \(RSSI)")
if peripheral.name == nil || peripheral.name == "" {
return
}
if self.peripheral == nil || self.peripheral.state == .disconnected {
stopScan()
self.peripheral = peripheral
central.connect(peripheral, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.delegate = self
peripheral.discoverServices([serviceUUID])
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
self.peripheral = nil
central.scanForPeripherals(withServices: nil, options: nil)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
self.peripheral = nil
}
func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
}
}
// MARK: - CBPeripheralDelegate
extension ViewController: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
print("No. of services: \(services.count)")
for service in services {
print(service.uuid)
if service.uuid == serviceUUID {
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
guard let characteristics = service.characteristics else { return }
for characteristic in characteristics {
print("characteristic: \(characteristic.uuid)")
if characteristic.uuid == characteristicUUID {
self.characteristic = characteristic
peripheral.setNotifyValue(true, for: characteristic)
peripheral.readValue(for: characteristic)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
print(error)
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if characteristic.uuid == characteristicUUID {
print("Got reply from: \(characteristic.uuid)")
print(characteristic.value)
if let data = characteristic.value, let string = String(data: data, encoding: String.Encoding.utf8) {
print(string)
} else {
print("No response!")
}
}
}
}
The discovering and connecting part works just fine. The problem is I don't receive that data string from the peripheral.
The method peripheral(_:didUpdateValueFor:error:) does get fired. I get the Got reply from: 19B10011-E8F2-537E-4F6C-D104768A1214 output in the console. However when I tried to see if there's any data by printing out the characteristic.value, it returns nil.
Not sure if it's something wrong with my code. Or I've configured the peripheral on LightBlue wrong. Does LightBlue send out data automatically? I don't see any Send button or anything anywhere either.
I uploaded a demo project here as well.
Your LightBlue configuration showing that you can only write value on that particular characteristic You have to make this read also