iOS Bluetooth периферийное устройство ManagerDidUpdateState никогда не вызывается
Я пытаюсь настроить свой iPhone в качестве монитора сердечного ритма и отправлять информацию, используя стандартную службу сердечного ритма, чтобы приложение, запущенное на моем ПК, могло получать данные. Я новичок в iOS, но у меня уже есть Bluetooth, работающий на Android и Windows. Я следую за информацией здесь, и я падаю на первое препятствие...
Как указано в документе, я сначала позвоню
CBPeripheralManager *myPeripheralManager = [[CBPeripheralManager alloc] initWithDelegate:(id<CBPeripheralManagerDelegate>)self queue:nil options:nil];
Я также реализую функцию обратного вызова ПериферическийМанигер DidUpdateState, но здесь кроется проблема. Этот обратный вызов никогда не запускается! Я ждал несколько минут, и ничего не произошло. Я подозреваю, что пропустил очень простой шаг, потому что я искал весь день и ничего не нашел в Интернете! Кто-нибудь может объяснить явные шаги, которые нужно предпринять как в коде, так и в физическом выполнении вещей с моим iPhone? Должен ли он иметь соединение до запуска этого обратного вызова? Это должно быть в паре с чем-либо?
Вот полный код. Все работает нормально, я не получаю никаких ошибок.
#import "ViewController.h"
@import CoreBluetooth;
@interface ViewController()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"App running...");
//Create the peripheral manager
CBPeripheralManager *myPeripheralManager = [[CBPeripheralManager alloc] initWithDelegate:(id<CBPeripheralManagerDelegate>)self queue:nil options:nil];
}
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
int state = peripheral.state;
NSLog(@"Peripheral manager state = %d", state);
//Set the UUIDs for service and characteristic
CBUUID *heartRateServiceUUID = [CBUUID UUIDWithString: @"180D"];
CBUUID *heartRateCharacteristicUUID = [CBUUID UUIDWithString:@"2A37"];
CBUUID *heartRateSensorLocationCharacteristicUUID = [CBUUID UUIDWithString:@"0x2A38"];
//char heartRateData[2]; heartRateData[0] = 0; heartRateData[1] = 60;
//Create the characteristics
CBMutableCharacteristic *heartRateCharacteristic =
[[CBMutableCharacteristic alloc] initWithType:heartRateCharacteristicUUID
properties: CBCharacteristicPropertyNotify
value:nil
permissions:CBAttributePermissionsReadable];
CBMutableCharacteristic *heartRateSensorLocationCharacteristic =
[[CBMutableCharacteristic alloc] initWithType:heartRateSensorLocationCharacteristicUUID
properties:CBCharacteristicPropertyRead
value:nil
permissions:CBAttributePermissionsReadable];
//Create the service
CBMutableService *myService = [[CBMutableService alloc] initWithType:heartRateServiceUUID primary:YES];
myService.characteristics = @[heartRateCharacteristic, heartRateSensorLocationCharacteristic];
//Publish the service
NSLog(@"Attempting to publish service...");
[peripheral addService:myService];
//Set the data
NSDictionary *data = @{CBAdvertisementDataLocalNameKey:@"iDeviceName",
CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:@"180D"]]};
//Advertise the service
NSLog(@"Attempting to advertise service...");
[peripheral startAdvertising:data];
}
- (void)peripheralManager:(CBPeripheralManager *)peripheral
didAddService:(CBService *)service
error:(NSError *)error {
if (error) {
NSLog(@"Error publishing service: %@", [error localizedDescription]);
}
else NSLog(@"Service successfully published");
}
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
error:(NSError *)error {
if (error) {
NSLog(@"Error advertising: %@", [error localizedDescription]);
}
else NSLog(@"Service successfully advertising");
}
@end
2 ответа
Предмет myPeripheralManager
освобождается, как только viewDidLoad
Метод возвращает, так как у вас есть только одна ссылка, указывающая на этот объект, и он выходит из области видимости.
Решение состоит в том, чтобы создать свойство в ViewController
который ссылается на случай CBPeripheralManager
:
@interface ViewController()
@property (nonatomic, strong) CBPeripheralManager *myPeripheralManager;
@end
а затем инициализировать свойство в viewDidLoad
:
self.myPeripheralManager = myPeripheralManager = [[CBPeripheralManager alloc] initWithDelegate:(id<CBPeripheralManagerDelegate>)self queue:nil options:nil];
Вы можете прочитать больше об управлении памятью (в частности, об автоматическом подсчете ссылок) в Objective-C.
Мое решение по этому вопросу:
import UIKit
import CoreBluetooth
class BluetoothManager: NSObject, CBPeripheralManagerDelegate {
static let sharedInstance = BluetoothManager()
var bluetoothPeripheralManager: CBPeripheralManager?
override fileprivate init() {
}
func start() {
bluetoothPeripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
}
// MARK - CBCentralManagerDelegate
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
var statusMessage = ""
switch peripheral.state {
case .poweredOn:
statusMessage = "Bluetooth Status: Turned On"
case .poweredOff:
statusMessage = "Bluetooth Status: Turned Off"
case .resetting:
statusMessage = "Bluetooth Status: Resetting"
case .unauthorized:
statusMessage = "Bluetooth Status: Not Authorized"
case .unsupported:
statusMessage = "Bluetooth Status: Not Supported"
default:
statusMessage = "Bluetooth Status: Unknown"
}
print(statusMessage)
if peripheral.state == .poweredOff {
//TODO: Update this property in an App Manager class
}
}}
Использование:
BluetoothManager.sharedInstance.start()
Запустите и включите / выключите и Bluetooth, должно появиться сообщение журнала, указывающее состояние Bluetooth.