如何在 xcode(swift) 和 phonegap 中将 运行 iPhone 作为背景灯塔
How to run iPhone as a beacon in background in both xcode(swift) and phonegap
我设法创建了一个将 phone 变成信标发射器的应用程序。
它在 xcode (Swift) 和 phonegap 上运行良好。
我的下一步是让它在后台作为灯塔工作(我正在为 iOS 10 开发)。
我在网上发现了与此类似的问题,但所有问题都已过时,即旧的 ios、objective-C 和过时的插件
如果有人能为我提供一个工作示例或指导我如何更改 xcode s(wift) 和 phonegap[=16 的代码,我将不胜感激=]
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();
对于这两个代码,在目标的后台功能中检查位置更新和后台获取。此外,两个播放列表都添加了隐私 - 位置始终使用说明
不幸的是,Apple 在 iOS 上阻止了在后台作为信标传输的能力。 所有 CoreBluetooth 标准广告实际上都被阻止了,因为广告位是有限的资源和后台多个应用程序会很快耗尽此资源。
Apple 确实有一个专有的备份系统,用于在后台宣传蓝牙服务,该系统使用特殊的溢出区域来包含服务标识符。但是,虽然此方案适用于在后台广告蓝牙服务,但不适用于广告信标,因为它破坏了格式。
底线:iOS 上的后台信标广告根本不起作用。对不起。
我设法创建了一个将 phone 变成信标发射器的应用程序。
它在 xcode (Swift) 和 phonegap 上运行良好。
我的下一步是让它在后台作为灯塔工作(我正在为 iOS 10 开发)。
我在网上发现了与此类似的问题,但所有问题都已过时,即旧的 ios、objective-C 和过时的插件
如果有人能为我提供一个工作示例或指导我如何更改 xcode s(wift) 和 phonegap[=16 的代码,我将不胜感激=]
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();
对于这两个代码,在目标的后台功能中检查位置更新和后台获取。此外,两个播放列表都添加了隐私 - 位置始终使用说明
不幸的是,Apple 在 iOS 上阻止了在后台作为信标传输的能力。 所有 CoreBluetooth 标准广告实际上都被阻止了,因为广告位是有限的资源和后台多个应用程序会很快耗尽此资源。
Apple 确实有一个专有的备份系统,用于在后台宣传蓝牙服务,该系统使用特殊的溢出区域来包含服务标识符。但是,虽然此方案适用于在后台广告蓝牙服务,但不适用于广告信标,因为它破坏了格式。
底线:iOS 上的后台信标广告根本不起作用。对不起。