使用专用 class 用 iPhone 模拟信标
Simulate beacon with iPhone using dedicated class
我想使用 iPhone 发送信标信号。目前它将在 Objective C 中实现,但有计划稍后将其转换为 Swift,因此我也有兴趣找出在此阶段可能遇到的任何重要差异。
在一些研究中,我发现了模拟信标的一些局限性
以及使用 class 而非视图控制器时出现的一些问题的信息,至少在 swift
中是这样
Using iPhone as iBeacon Transmitter
在最后一个 link 中,我找到了 link 到 Swift 的教程,用于使用 iPhone 模拟 iBeacon - 代码放在视图控制器中,它可以在这个地方工作。
https://www.hackingwithswift.com/example-code/location/how-to-make-an-iphone-transmit-an-ibeacon
但是如果我想让应用程序做一些其他事情而不仅仅是传输 BLE 信号,那么从 View Controller 使用 Core Bluetooth 是一个严重的限制。而这些其他东西需要关闭我的控制器。
很快我将尝试为 Objective C 创建一些工作代码,稍后为 Swift 创建一些工作代码,用于发射 BLE 信号并仍然改变可见的视图控制器。但是也许有人做过类似的事情并且能够说出是否有任何问题,就像之前提到的那样
是的,您绝对可以在 ViewController
之外的 iOS 上设置信标传输。下面是一个简单的 Swift class,我曾经在许多项目中这样做过。
但是请注意,虽然您可以使用这样的 class 来做广告,而不管哪个 ViewController 在前台,但如果您的整个应用程序都在后台,则广告将停止。这是 Apple iOS 的限制。有关详细信息,请参阅 。
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")
}
}
}
我想使用 iPhone 发送信标信号。目前它将在 Objective C 中实现,但有计划稍后将其转换为 Swift,因此我也有兴趣找出在此阶段可能遇到的任何重要差异。
在一些研究中,我发现了模拟信标的一些局限性
以及使用 class 而非视图控制器时出现的一些问题的信息,至少在 swift
中是这样Using iPhone as iBeacon Transmitter
在最后一个 link 中,我找到了 link 到 Swift 的教程,用于使用 iPhone 模拟 iBeacon - 代码放在视图控制器中,它可以在这个地方工作。
https://www.hackingwithswift.com/example-code/location/how-to-make-an-iphone-transmit-an-ibeacon
但是如果我想让应用程序做一些其他事情而不仅仅是传输 BLE 信号,那么从 View Controller 使用 Core Bluetooth 是一个严重的限制。而这些其他东西需要关闭我的控制器。
很快我将尝试为 Objective C 创建一些工作代码,稍后为 Swift 创建一些工作代码,用于发射 BLE 信号并仍然改变可见的视图控制器。但是也许有人做过类似的事情并且能够说出是否有任何问题,就像之前提到的那样
是的,您绝对可以在 ViewController
之外的 iOS 上设置信标传输。下面是一个简单的 Swift class,我曾经在许多项目中这样做过。
但是请注意,虽然您可以使用这样的 class 来做广告,而不管哪个 ViewController 在前台,但如果您的整个应用程序都在后台,则广告将停止。这是 Apple iOS 的限制。有关详细信息,请参阅
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")
}
}
}