Я создал приложение, которое является периферийным устройством, работающим на моем iPhone. Это периферийное устройство является рекламным и объединяет услуги и характеристики. С помощью nrfConnect или других приложений сканирования я могу подключиться и увидеть все созданные службы / характеристики, пока мое приложение находится на переднем плане. Чтобы включить фоновый режим, я следовал официальной документации: https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html
Сегодня, когда я убиваю приложение вручную, фоновый режим работает, и я вижу свое периферийное устройство (без его локального name, потому что iOS удалите его, но я могу распознать адрес ma c, предоставленный nrfConnect). Моя проблема заключается в том, что я пытаюсь подключиться к периферийному устройству, когда приложение убито и находится в фоновом режиме. Все сервисы отсутствуют !! В документации Apple объясняется, что мы можем восстанавливать службы в фоновом режиме с помощью метода делегата willRestoreState
и устанавливать 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)
}
}
}