从不调用iOS蓝牙peripheralManagerDidUpdateState

我正在尝试将我的iPhone设置为心率监测器并使用标准心率服务发送信息,以便我在PC上运行的应用程序可以检索数据。 我是iOS的新手,但我之前在Android和Windows上运行了蓝牙function。 我在这里关注这些信息,我正陷入第一道障碍……

正如文档中所指出的,我先打电话

CBPeripheralManager *myPeripheralManager = [[CBPeripheralManager alloc] initWithDelegate:(id)self queue:nil options:nil]; 

我还实现了peripheralManagerDidUpdateState回调,但这就是问题所在。 这个回调永远不会运行! 我等了几分钟,什么都没发生。 我怀疑我错过了一个非常简单的步骤,因为我整天都在搜索,并且在网上找不到任何东西! 任何人都可以解释在代码和物理上用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)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 

一旦viewDidLoad方法返回,对象myPeripheralManager被释放,因为您只有一个引用指向此对象并且它超出范围。

解决方案是在ViewController创建一个属性,该属性引用CBPeripheralManager的实例:

 @interface ViewController() @property (nonatomic, strong) CBPeripheralManager *myPeripheralManager; @end 

然后在viewDidLoad初始化该属性:

 self.myPeripheralManager = myPeripheralManager = [[CBPeripheralManager alloc] initWithDelegate:(id)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() 

启动你的启动和关闭和蓝牙应该出现一条指示蓝牙状态的日志消息。