进入信标区域时如何在后台作为信标做广告

Posted

技术标签:

【中文标题】进入信标区域时如何在后台作为信标做广告【英文标题】:how to advertise in the background as a beacon when entering a beacon region 【发布时间】:2017-08-23 13:05:17 【问题描述】:

我目前正在开发一个严重依赖 iBceaons 的应用程序。

我设法创建了一个信标区域,当进入该区域时,它会在后台唤醒应用进程 10 秒。

下一步是让手机在后台进入该区域时自动做广告

当前,当应用程序打开时,它会保持测距并在区域内时作为信标传输 当应用程序在后台时,它的范围为 10 秒,但在进入区域时不会作为信标传输

那么有没有办法让手机在进入区域时在后台作为信标进行传输?

我已经查看了Apple's background Bluetooth,其中提到在后台传输时广告包不同。我也看过This Solution,但这个解决方案不使用核心位置,所以它在进入区域时无法唤醒应用程序

import UIKit
import CoreLocation
import CoreBluetooth
class ViewController: 
UIViewController,CLLocationManagerDelegate,CBPeripheralManagerDelegate 

var locationManager: CLLocationManager!
var localBeacon: CLBeaconRegion!
var beaconPeripheralData: NSDictionary!
var peripheralManager: CBPeripheralManager!

let myCustomServiceUUID = CBUUID(string:"5A4BCFCE-174E-4BAC-A814-092E77F6B7E5")

override func viewDidLoad() 
    super.viewDidLoad()
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.requestAlwaysAuthorization()

    




override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()


func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) 
    if status == .authorizedAlways 
        if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) 
            if CLLocationManager.isRangingAvailable() 
                startScanning()
            
        
    


func startScanning() 
    let uuid = UUID(uuidString: "48de4980-968d-11e4-b4a9-0800200c9a66")!
    let beaconRegion = CLBeaconRegion(proximityUUID: uuid, major: 1, minor: 1, identifier: "region1")
       beaconRegion.notifyEntryStateOnDisplay=true;
    locationManager.startMonitoring(for: beaconRegion)
    locationManager.startRangingBeacons(in: beaconRegion)


func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) 

    if(beacons.count > 0) 
        let nearestBeacon:CLBeacon = beacons[0] as CLBeacon

    NSLog("RSSI value is %ld", nearestBeacon.rssi);
        initLocalBeacon() // Here I'm transmitting as a beacon along with ranging when entering or within a region  which works fine the app is open but not transmitting while in background 



    


func locationManager(_ manager: CLLocationManager,didDetermineState state: CLRegionState,for region: CLRegion)    

    switch state 
    case .inside:
        NSLog("locationManager didDetermineState INSIDE  %@", region.identifier);


    case .outside:
        NSLog("locationManager didDetermineState OUTSIDE  %@", region.identifier);

    case .unknown:
        NSLog("locationManager didDetermineState OTHER  %@", region.identifier);

    


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

    let localBeaconUUID = "5A4BCFCE-174E-4BAC-A814-092E77F6B7E5"
    let localBeaconMajor: CLBeaconMajorValue = 2
    let localBeaconMinor: CLBeaconMinorValue = 1

    let uuid = UUID(uuidString: localBeaconUUID)!
    localBeacon = CLBeaconRegion(proximityUUID: uuid, major: localBeaconMajor, minor: localBeaconMinor, identifier: "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()
    


我在功能的后台模式中选择了作为 BLE 附件的行为,并在播放列表中添加了隐私 - 蓝牙外设使用说明

【问题讨论】:

【参考方案1】:

抱歉,ios 不会让您的应用在后台发布符合 iBeacon 规范的 BLE 数据包。正如您在问题中提到的,Apple 改变了在后台发出的背景广告的外观,因此,它们不会触发 CoreLocation 输入事件来唤醒后台接收应用程序。

有一些不完美的选择:

    您可以在后台使用其他信标广告并唤醒您的应用。这不会像 iBeacon 那样快,但它会在几分钟内唤醒您的应用程序。这是执行此操作的设置:https://github.com/Decemberlabs/AltBeacon

    您可以在应用处于前台时宣传 iBeacon,并尝试通过本地通知让用户将应用带到前台。

    如果附近有您的应用程序的其他前台副本(基于后台信标检测),您可以使用网络服务在您的应用程序在后台运行的 10 秒内通知他们您的存在。此通知可以告诉他们代表您开始投放广告。

【讨论】:

感谢您的回复@davidgyoung。我不能使用核心位置唤醒应用程序并在应用程序唤醒后使用核心蓝牙传输吗?所以基本上不是调用 initLocalBeacon() ,而是调用一个会发出 altBeacon 的函数? 是的,您可以这样做。您基本上可以让您的应用程序监听两种信标(一种具有核心位置,一种具有核心蓝牙)。如果应用程序在前台,它可以发出 iBeacon 以便其他人更快地检测到。如果在后台它可以发出 altBeacon 进行检测,它仍然可以工作,但速度较慢。

以上是关于进入信标区域时如何在后台作为信标做广告的主要内容,如果未能解决你的问题,请参考以下文章

在后台监控期间接收来自信标区域检测的通知

在后台或应用未运行时监控 Bluecats 信标

iOS 在后台监控/测距信标会消耗大量电池

iOS 广告信标在后台

iOS 15 在进入 BLE 信标区域时不会唤醒应用

ibeacons 和地理围栏结合 swift