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.
peripheralManagerDidUpdateState
– Paulw11peripheralManagerDidUpdateState
delegate method. I am starting advertising incentralManagerDidUpdateState
. This was also taking place inviewDidLoad()
but I have since commented this out. – Mark TyersperipheralManagerDidUpdateState
method is in the code you have shown, it just has an empty implementation - you need to check for the power on state before advertising, but more importantly yourCBMutableService
instance needs to be stored in a property, not a local variable otherwise it will be released oncecentralManagerDidUpdateState
exits;CBPeripheralManager
does not retain the CBMutableService – Paulw11