2

I want to transmit beacon signal using iPhone. For now it will be implemented in Objective C, but there is a plan to convert it to Swift later, so I'm also interested in finding any important differences I can encounter at this phase.

In some research I was able to find some limitations in simulating beacon

Can I make iPhone/iPad broadcast as Eddystone Beacon?

and also informations of some problems when using class other than view controller, at least in swift

Using iPhone as iBeacon Transmitter

In this last link I found link to Swift tutorial for simulating iBeacon with iPhone - code is placed in View Controller and it works in this place.

https://www.hackingwithswift.com/example-code/location/how-to-make-an-iphone-transmit-an-ibeacon

But using Core Bluetooth from View Controller is serious limitation if I want app to do some other stuff than just transmitting BLE signal. And this other stuff needs dismissing my controller.

Soon I will try to create some working code for Objective C and later for Swift for emitting BLE signal and still changing visible View Controllers. But maybe someone had done something like that and will be able to say if there was any problems, like mentioned before

Community
  • 1
  • 1
Adam Tucholski
  • 1,067
  • 11
  • 27
  • There shouldn't be an issue about not doing it as not a ViewController subclass. Using a singleton should work. – Larme Dec 08 '16 at 10:50

1 Answers1

2

Yes, you can absolutely set up beacon transmitting on iOS outside a ViewController. Below is a simple Swift class that I have used to do so on a number of projects.

Note, however, that while you can use a class like this to advertise regardless of which ViewController is in the foreground, advertising will stop if your entire app is in the background. This is an Apple iOS limitation. See here for more info.

  import Foundation
  import CoreBluetooth
  import CoreLocation
  import UIKit

  class BeaconTransmitter: NSObject, CBPeripheralManagerDelegate {
    var region: CLBeaconRegion?
    var on = false
    var _peripheralManager: CBPeripheralManager?
    var peripheralManager: CBPeripheralManager {
      if _peripheralManager == nil {
        _peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
      }
      return _peripheralManager!
    }
    override init() {
      super.init()
    }

    func stop() {
      on = false
      peripheralManager.stopAdvertising()
    }

    func start(region: CLBeaconRegion) {
      on = true
      self.region = region
      startTransmitting()
    }

    func startTransmitting() {
      if let region = region {
        let peripheralData = region.peripheralData(withMeasuredPower: -59) as Dictionary
        peripheralManager.stopAdvertising()
        peripheralManager.startAdvertising(peripheralData as? [String : AnyObject])
      }
    }

    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
      if(peripheral.state == .poweredOn) {
        if on {
          startTransmitting()
        }
      }
      else if(peripheral.state == .poweredOff) {
        NSLog("Bluetooth is off")
      }
      else if(peripheral.state == .unsupported) {
        NSLog("Bluetooth not supported")
      }
    }
  }
Community
  • 1
  • 1
davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • Thank you. Working code in Swift is enough to prove that there won't be a problem. It seems that in linked question something was wrong (maybe not calling method or not retaining instance of class... Out of curiosity - setting power for peripheral was necessary or it was just free choice of "iBeacon" signal strength? – Adam Tucholski Dec 09 '16 at 09:07
  • Well, you *have* to set the power value, because that is how the API works. If you don't supply it, you'll get a compiler error. That said, you can put any value in there you want. The only consequence will be incorrect distance estimates on the receiving end. The power value is intended to tell the receiver how strong the signal should be in dBM when it is one meter away. – davidgyoung Dec 09 '16 at 14:33
  • I understand. In meantime I found [here](https://github.com/AltBeacon/altbeacon-transmitter-android) information that this value is equivalent to the non-configurable transmitter power of an iPhone. So now I'm happy and aware. Thanks :) – Adam Tucholski Dec 09 '16 at 15:05