theappledev
theappledev

Reputation: 33

Background Bluetooth(BLE) Transmit and Scan

Code works great when the application is open(foreground) but, It does not run in the background. I have all background modes enabled. I have also added Background location updates using .allowsBackgroundLocationUpdates implemented. Not sure where to go from here. Code is below:

 import UIKit
 import CoreLocation
 import CoreBluetooth

 class iDevice: UIViewController, CBPeripheralManagerDelegate, CLLocationManagerDelegate{

@IBOutlet weak var device: UILabel!

@IBOutlet weak var deviceImg: UIImageView!
@IBOutlet weak var distance: UILabel!

var beaconRegion : CLBeaconRegion!
var beaconPeripheralData : NSDictionary!
var peripheralManager : CBPeripheralManager!

var locationManager : CLLocationManager!

override func viewDidLoad() {
    super.viewDidLoad()
    initBeaconRegion()
    initTransmit()

    locationManager = CLLocationManager.init()
    locationManager.delegate = self
    locationManager.requestWhenInUseAuthorization()
    locationManager!.allowsBackgroundLocationUpdates = true
    locationManager!.pausesLocationUpdatesAutomatically = false

    startScanningForBeaconRegion(beaconRegion: getBeaconRegion())

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad) {
        self.device.text = "iPhone"
        self.deviceImg.image =  UIImage(named: "phone")!

    }

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.phone) {
        self.device.text = "iPad"
        self.deviceImg.image =  UIImage(named: "ipad")!
    }

}

func initTransmit(){
    beaconPeripheralData = beaconRegion .peripheralData(withMeasuredPower: nil)
    peripheralManager = CBPeripheralManager.init(delegate: self, queue: nil)
}
func initBeaconRegion() {
    beaconRegion = CLBeaconRegion.init(proximityUUID: UUID.init(uuidString: "E06F95E4-FCFC-42C6-B4F8-F6BAE87EA1A0")!,
                                       major: 1233,
                                       minor: 45,
                                       identifier: "com.peard.idevices")
}
   func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
    if (peripheral.state == .poweredOn) {
        peripheralManager .startAdvertising(beaconPeripheralData as? [String : Any])
        print("Powered On")

    } else {
        peripheralManager .stopAdvertising()
        print("Not Powered On, or some other error")
    }
}

func getBeaconRegion() -> CLBeaconRegion {
    let beaconRegion = CLBeaconRegion.init(proximityUUID: UUID.init(uuidString: "E06F95E4-FCFC-42C6-B4F8-F6BAE87EA1A0")!, identifier: "com.peard.idevices")
    return beaconRegion
}

func startScanningForBeaconRegion(beaconRegion: CLBeaconRegion) {
    print(beaconRegion)
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.startMonitoring(for: beaconRegion)

    locationManager.startRangingBeacons(in: beaconRegion)
}


func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    let beacon = beacons.last

    if beacons.count > 0 {

        if beacon?.proximity == CLProximity.unknown {
            distance.text = "Unknown"

        } else if beacon?.proximity == CLProximity.immediate {
            distance.text = "within 3ft"

        } else if beacon?.proximity == CLProximity.near {
           distance.text = "within 5ft"

        } else if beacon?.proximity == CLProximity.far {
            distance.text = "within 20 ft"

        }

    } else {
        print("no")
    }

    print("Ranging")
}


override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent}
@IBAction func dismiss(_ sender: Any) { self.dismiss(animated: true, completion: nil)}

}

Thank you in Advance!!!

Upvotes: 0

Views: 628

Answers (1)

Keshav Raj
Keshav Raj

Reputation: 476

Your peripheral advertisement behaviour is different when it is in the background mode:-

  1. CBAdvertisementDataLocalNameKey advertisement key is ignored and local name of peripheral is not advertised.
  2. All service UUIDS contained in value of CBAdvertismentDataServiceUUIDS advertisement key are placed in special overflow area. They can be discovered only by iOS device explicitly scanning for them.
  3. If all apps are advertising then frequency of advertisment packet decreases.

I think you are having 2nd problem.For more details see Apple programming guide for background processing with core bluetooth.

Upvotes: 0

Related Questions