需要解决的问题:类似小米9号那样实现感应解锁,也就是当手机靠近电动车的时候,电动车就可以解锁,即使app不打开
本人测试能实现的效果:用蓝牙后台模式,app在后台,app在后台后被系统杀死,app在后台后被系统杀死然后被手动杀死,都可以通过蓝牙发数据实现感应解锁。但是app在前台或是在后台被手动杀死,不能实现感应解锁用ibeacon,通过服务器利用网络给电动车发数据,app直接被手动杀死,也可以实现感应解锁2.demo下载 2.1 蓝牙中心,ibeacon搜索方(手机)
XXyueliang/blue-tooth-background - gitee
点击button搜索蓝牙设备
点击连接
2.2 蓝牙外设,ibeacon广播方(模拟电动车,带ibeacon的蓝牙设备)
XXyueliang/beacon-sample - gitee
打开开关,开始广播,黄色界面可以展示接收到的从蓝牙中心发过来的数据3.代码示例和解说 3.1 添加Background Modes, 配置Info.plist
如果不用ibeacon,app在挂起状态靠近蓝牙设备被系统唤醒时launchOptions?[UIApplication.LaunchOptionsKey.bluetoothCentrals][0] = “myCentralManagerIdentifier”, 搜索蓝牙设备会调用willRestoreState代理方法. 创建蓝牙中心对象时用CBCentralManager.init(delegate: self, queue: nil, options: [CBCentralManagerOptionRestoreIdentifierKey:“myCentralManagerIdentifier”])
如果使用ibeacon,app在关闭状态靠近ibeacon设备被系统唤醒时launchOptions[UIApplication.LaunchOptionsKey.location] = 1(true)
//创建单例
static let shared = XYCBBase()
override init() {
super.init()
xyCentralManager = CBCentralManager.init(delegate: self, queue: nil, options: [CBCentralManagerOptionRestoreIdentifierKey:"myCentralManagerIdentifier"])
}
//MARK: willRestoreState -
func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
printXY(dict, obj: self, line: #line)
if let arr = dict[CBCentralManagerRestoredStatePeripheralsKey] {
let peripheralArr:[CBPeripheral] = (arr as! NSArray) as! [CBPeripheral]
let meek = peripheralArr[0]
MyFileManager.shared.sendBluetoothState(state: "willRestoreState", content: meek.name ?? "无名")
let data = Data([9,8,5])
BTBManager.shared.peripheral = meek
XYCentralManager.shared.connect(peripheral: meek) { (bool, error) in
}
// XYCentralManager.shared.write(peripheral: meek, characteristic: BTBManager.shared.characteristic, data: data, errorClosure: nil)
}else{
MyFileManager.shared.sendBluetoothState(state: "willRestoreState", content: "无外设")
}
}
//
// AppDelegate.swift
// BlueToothBackground
//
// Created by macvivi on 2021/11/3.
//
import UIKit
import CoreLocation
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let centralManagerIdenntifiers = launchOptions?[UIApplication.LaunchOptionsKey.bluetoothCentrals]
if let arr = centralManagerIdenntifiers {
let arrStr:[String] = arr as! [String]
MyFileManager.shared.sendBluetoothState(state: "didFinishLaunchingWithOptions", content: arrStr[0])
XYCentralManager.shared.startScan { (periphral) in }
// XYCentralManager.shared
} else if let launch = launchOptions {
let num = launch[UIApplication.LaunchOptionsKey.location] as! NSNumber
MyFileManager.shared.sendBluetoothState(state: "didFinishLaunchingWithOptions", content: String(num.intValue))
}else{
MyFileManager.shared.sendBluetoothState(state: "didFinishLaunchingWithOptions", content: "noLaunchOptions")
}
//把这句代码注释掉就是只用蓝牙,不用ibeacon
beacon()
return true
}
let defaultUUID = "E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"
var locationManager = CLLocationManager()
func beacon(){
locationManager.delegate = self
self.locationManager.requestAlwaysAuthorization()
let beaconRegion = CLBeaconRegion(proximityUUID: UUID(uuidString: defaultUUID)!, identifier: defaultUUID)
beaconRegion.notifyEntryStateOnDisplay = true
beaconRegion.notifyOnEntry = true
beaconRegion.notifyOnExit = true
self.locationManager.startMonitoring(for: beaconRegion)
// self.locationManager.startRangingBeacons(in: beaconRegion)
}
}
extension AppDelegate:CLLocationManagerDelegate{
// MARK: - Location Manager Delegate
/// - Tag: didDetermineState
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
print(#function)
print(state.rawValue)
let beaconRegion = (region as? CLBeaconRegion)!
if state == .inside {
manager.startRangingBeacons(in: beaconRegion)
} else {
manager.stopRangingBeacons(in: beaconRegion)
}
}
func locationManager(_ manager: CLLocationManager, didStartMonitoringFor region: CLRegion) {
print(#function)
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
print(#function)
MyFileManager.shared.sendBluetoothState(state: "didEnterRegion", content: "")
//这里可以通过网络发命令给蓝牙设备解锁
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
MyFileManager.shared.sendBluetoothState(state: "didExitRegion", content: "")
print(#function)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(#function)
}
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
printXY(#function, obj: self, line: #line)
MyFileManager.shared.sendBluetoothState(state: "didRangeBeacons", content: "")
if beacons.count > 0 {
let beacon = beacons[0]
printXY(beacon.proximity.rawValue, obj: self, line: #line)
}
}
}
3.3 当外设开关状态发生变化时(或者蓝牙中心离开靠近外设时),app如果处于挂起或是关闭状态,会被系统唤醒,活跃10秒,来处理相关事件
4.参考博客,下面的博客记录了我解决问题的过程
ios swift app在后台或是被杀死了怎样使用蓝牙
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)