简体   繁体   中英

How to run iPhone as a beacon in background in both xcode(swift) and phonegap

I managed to create an app which turns the phone into a beacon emitter.

It works fine on xcode (Swift) and phonegap .

The next step for me is making it work in the background as a beacon (I'm developing for iOS 10).

I found similar questions to this online but all of them were out of date ie old ios , objective-C and outdate plug-ins

would really appreciate it if someone can provide me with a working example or guide me on what to change in my code for both an xcode s(wift) and phonegap

Xcode (Swift 3)

import UIKit
import CoreLocation
import CoreBluetooth

class ViewController: UIViewController,CLLocationManagerDelegate,CBPeripheralManagerDelegate,UITextFieldDelegate{

    var locationManager = CLLocationManager()
    var startLocation: CLLocation!
    var localBeacon: CLBeaconRegion!
    var beaconPeripheralData: NSDictionary!
    var peripheralManager: CBPeripheralManager!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        locationManager.delegate = self

        locationManager.requestAlwaysAuthorization()

        bleSwitch.addTarget(self, action: #selector(ViewController.bleSwitchUpdated(_:)), for: UIControlEvents.valueChanged)

        major.delegate=self
        minor.delegate=self
        txPower.delegate=self

    }

    @IBOutlet weak var minor: UITextField!
    @IBOutlet weak var major: UITextField!
    @IBOutlet weak var txPower: UITextField!
    @IBOutlet weak var bleSwitch: UISwitch!
    @IBOutlet weak var bleView: UIView!
    @IBAction func bleSwitchUpdated(_ sender: UISwitch) {
        if bleSwitch.isOn {
            initLocalBeacon()
            bleView.isHidden = false;
        //bleSwitch.setOn(true, animated: false)
        }
        else {
        stopLocalBeacon()
            bleView.isHidden = true;
        }
    }

    func initLocalBeacon() {
        if localBeacon != nil {
            stopLocalBeacon()
        }

        let localBeaconUUID = "5A4BCFCE-174E-4BAC-A814-092E77F6B7E5"
        let localBeaconMajor: CLBeaconMajorValue = UInt16(major.text!)!
        let localBeaconMinor: CLBeaconMinorValue = UInt16(minor.text!)!

        let uuid = UUID(uuidString: localBeaconUUID)!
        localBeacon = CLBeaconRegion(proximityUUID: uuid, major: localBeaconMajor, minor: localBeaconMinor, identifier: "Your private identifer here")

        beaconPeripheralData = localBeacon.peripheralData(withMeasuredPower: -59)
        peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
    }

    func stopLocalBeacon() {
        peripheralManager.stopAdvertising()
        peripheralManager = nil
        beaconPeripheralData = nil
        localBeacon = nil
    }

    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
        if peripheral.state == .poweredOn {
            peripheralManager.startAdvertising(beaconPeripheralData as! [String: AnyObject]!)
        } else if peripheral.state == .poweredOff {
            peripheralManager.stopAdvertising()
        }
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true

    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
        if bleSwitch.isOn == true{
        stopLocalBeacon()
            initLocalBeacon()
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

Phonegap

    var app = (function()
{

           // Application object.
    var app = {};

    // Background flag.
    var mAppInBackground = false;

        app.initialize = function()
    {
        document.addEventListener('deviceready', onDeviceReady, false);
        document.addEventListener('pause', onAppToBackground, false);
        document.addEventListener('resume', onAppToForeground, false);
    };

    function onDeviceReady()
    {
        startMonitoringAndRanging();
        startNearestBeaconDisplayTimer();
        displayRegionEvents();

    }

    function onAppToBackground()
    {
        mAppInBackground = true;
        stopNearestBeaconDisplayTimer();
    }

    function onAppToForeground()
    {
        mAppInBackground = false;
        startNearestBeaconDisplayTimer();
        displayRegionEvents();
    }


    function startMonitoringAndRanging()
    {

        // Request permission from user to access location info.
        cordova.plugins.locationManager.requestAlwaysAuthorization();

           BleconOn();

    }


           function BleconOn(){
           var uuid = '00000000-0000-0000-0000-000000000000';
           var identifier = 'advertisedBeacon';
           var minor = 2000;
           var major = 5;
           var beaconRegion = new cordova.plugins.locationManager.BeaconRegion(identifier, uuid, major, minor);

           var delegate = new cordova.plugins.locationManager.Delegate();


           delegate.peripheralManagerDidStartAdvertising = function(pluginResult) {
           console.log('peripheralManagerDidStartAdvertising: '+ JSON.stringify(pluginResult.region));
           };
           // Event when bluetooth transmission state changes
           // If 'state' is not set to BluetoothManagerStatePoweredOn when advertising cannot start
           delegate.peripheralManagerDidUpdateState = function(pluginResult) {
           console.log('peripheralManagerDidUpdateState: '+ pluginResult.state);
           };

           cordova.plugins.locationManager.setDelegate(delegate);

           // Verify the platform supports transmitting as a beacon
           cordova.plugins.locationManager.isAdvertisingAvailable()
           .then(function(isSupported){

                 if (isSupported) {
                 cordova.plugins.locationManager.startAdvertising(beaconRegion)
                 .fail(conole.error)
                 .done();
                 } else {
                 console.log("Advertising not supported");
                 }
                 })
           .fail(function(e) { console.error(e); })
           .done();
           }

           function BleconOff(){

           cordova.plugins.locationManager.stopAdvertising()
           .fail(console.error)
           .done();
           }



    return app;

})();

app.initialize();

for both codes , the location updates and background fetch are checked in the background capabilities for the target. Also , Privacy - Location Always Usage Description is added on both playlists

Unfortunately, Apple blocks the ability to transmit as a beacon in the background on iOS. All CoreBluetooth standard advertisements are actually blocked, because advertising slots are a limited resource and multiple apps in the background would exhaust this resource quickly.

Apple does have a proprietary backup system for advertising Bluetooth services in the background that uses a special overflow area to include the service identifiers. But while this scheme works for advertising Bluetooth services in the background, it does not work for advertising beacons, because it breaks the format.

Bottom line: background beacon advertising on iOS just does not work. Sorry.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM