我创建了一个应用程序,它是在我的 iPhone 上运行的 ble 外围设备。这个外设是广告,集成了服务和特性。使用 nrfConnect 或其他可扫描应用程序,只要我的应用程序处于前台,我就可以连接并查看所有创建的服务/特征。为了启用后台模式,我遵循了官方文档:https ://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html
今天,当我手动杀死应用程序时,后台模式工作,我可以看到我的外围设备(没有他的本地名称,因为 iOS 删除了它,但我可以识别 nrfConnect 给出的 mac 地址)。我的问题是当我在应用程序被终止并处于后台模式时尝试连接到外围设备时。所有服务都不见了!!willRestoreState
Apple 的文档解释说,我们可以使用委托方法在后台恢复服务,并CBPeripheralManagerRestoredStateServicesKey
在初始化CBPeripheralManager
. 我做了所有这些步骤,但服务没有恢复......如果有人有想法?
这是我的AppDelegate
文件的完整代码:
import UIKit
import CoreBluetooth
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CBPeripheralManagerDelegate {
var window: UIWindow?
var peripheralManager: CBPeripheralManager!
var deviceName = "DIGITALBLEND"
var dataToBeAdvertised: [String: [CBUUID]]!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.backgroundColor = UIColor.white
UIView.transition(with: self.window!, duration: 0.5, options: UIView.AnimationOptions.transitionCrossDissolve, animations: {
self.window?.rootViewController = ViewController()
self.window?.makeKeyAndVisible()
}, completion: nil)
let optionsPeripheral = [
CBPeripheralManagerOptionRestoreIdentifierKey: self.deviceName,
CBPeripheralManagerRestoredStateServicesKey: [
CBUUID(string: "1ABB0000-542A-3BA1-C243-6F5AAF168DB7"),
CBUUID(string: "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"),
CBUUID(string: "0xFE59"),
],
] as [String : Any]
self.peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: optionsPeripheral)
return true
}
// MARK: Peripheral Manager Functions
func startAdvertising() {
//Start advertising
let advertisementData = [
CBAdvertisementDataLocalNameKey: self.deviceName,
]
if self.peripheralManager.isAdvertising == false {
self.peripheralManager.startAdvertising(advertisementData)
}
}
func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {
if peripheral.isAdvertising{
print("My Device Started Advertising")
}
}
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
if peripheral.state == .poweredOn {
//Add services
self.createServices()
} else {
print("Bluetooth is not active")
}
}
func createServices() {
//Primary Service
let primaryServiceUUID = CBUUID(string: "1ABB0000-542A-3BA1-C243-6F5AAF168DB7")
let primaryService = CBMutableService(type: primaryServiceUUID, primary: true)
//Nordic UARD Service
let nusUUID = CBUUID(string: "6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
let nusService = CBMutableService(type: nusUUID, primary: true)
//Secure DFU Service
let dfuUUID = CBUUID(string: "0xFE59")
let dfuService = CBMutableService(type: dfuUUID, primary: true)
//Create characteristics
self.createCharacteristic_PRIMARY(service: primaryService)
self.createCharacteristic_NUS(service: nusService)
self.createCharacteristic_DFU(service: dfuService)
}
func createCharacteristic_PRIMARY(service : CBMutableService) {
let permissions: CBAttributePermissions = [.readable, .writeable]
//Characteristic 1
let characteristicUUID_1 = CBUUID(string: "1ABB0001-542A-3BA1-C243-6F5AAF168DB7")
let properties_1: CBCharacteristicProperties = [.read, .write]
let characteristic_1 = CBMutableCharacteristic(
type: characteristicUUID_1,
properties: properties_1,
value: nil,
permissions: permissions)
//Characteristic 2
let characteristicUUID_2 = CBUUID(string: "1ABB0002-542A-3BA1-C243-6F5AAF168DB7")
let properties_2: CBCharacteristicProperties = [.notify, .read, .write]
let characteristic_2 = CBMutableCharacteristic(
type: characteristicUUID_2,
properties: properties_2,
value: nil,
permissions: permissions)
//Add characteristic to service
service.characteristics = [characteristic_1, characteristic_2]
self.peripheralManager.add(service)
}
func createCharacteristic_NUS(service : CBMutableService) {
let permissions: CBAttributePermissions = [.readable, .writeable]
//Characteristic 1 - RX
let characteristicUUID_1 = CBUUID(string: "6E400002-B5A3-F393-E0A9-E50E24DCCA9E")
let properties_1: CBCharacteristicProperties = [.write]
let characteristic_1 = CBMutableCharacteristic(
type: characteristicUUID_1,
properties: properties_1,
value: nil,
permissions: permissions)
//Characteristic 2 - TX
let characteristicUUID_2 = CBUUID(string: "6E400003-B5A3-F393-E0A9-E50E24DCCA9E")
let properties_2: CBCharacteristicProperties = [.notify]
let characteristic_2 = CBMutableCharacteristic(
type: characteristicUUID_2,
properties: properties_2,
value: nil,
permissions: permissions)
//Add characteristic to service
service.characteristics = [characteristic_1, characteristic_2]
self.peripheralManager.add(service)
}
func createCharacteristic_DFU(service : CBMutableService) {
let permissions: CBAttributePermissions = [.readable, .writeable]
//Characteristic 1 - Buttonless DFU
let characteristicUUID_1 = CBUUID(string: "8EC90003-F315-4F60-9FB8-838830DAEA50")
let properties_1: CBCharacteristicProperties = [.indicate, .write]
let characteristic_1 = CBMutableCharacteristic(
type: characteristicUUID_1,
properties: properties_1,
value: nil,
permissions: permissions)
//Add characteristic to service
service.characteristics = [characteristic_1]
self.peripheralManager.add(service)
}
func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
if error == nil{
print("success publishing the service")
self.startAdvertising()
} else {
print(error?.localizedDescription ?? "error publishing service")
}
}
// CENTRAL read from TX
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
print("salut")
}
// CENTRAL read from RX
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
}
func peripheralManager(_ peripheral: CBPeripheralManager, willRestoreState dict: [String : Any]) {
self.peripheralManager = peripheral
// Note: restoring CBPeripheralManager services only works on iOS 11.2+
guard let services = dict[CBPeripheralManagerRestoredStateServicesKey] as? [CBMutableService] else {
return
}
for service in services {
self.peripheralManager.add(service)
}
}
}