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- Paulw11peripheralManagerDidUpdateStatedelegate method. I am starting advertising incentralManagerDidUpdateState. This was also taking place inviewDidLoad()but I have since commented this out. - Mark TyersperipheralManagerDidUpdateStatemethod 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 yourCBMutableServiceinstance needs to be stored in a property, not a local variable otherwise it will be released oncecentralManagerDidUpdateStateexits;CBPeripheralManagerdoes not retain the CBMutableService - Paulw11