ios – 扫描特定CBUUID时,Core Bluetooth无法找到外围设备

ios – 扫描特定CBUUID时,Core Bluetooth无法找到外围设备,第1张

概述似乎这个问题被“回答”了 here,但没有任何代码来表明他们做了不同的事情,我不得不问一个新问题. 我有自己的代码具有相同的行为,在OS X上使用Core Bluetooth的CBCentralManager扫描特定的CBUUID并没有发现一个iOS设备充当CBPeripheralManager的外围设备(除非它及其服务先前已被发现).为了查看我的代码是否有问题,我下载了Apple’s sampl 似乎这个问题被“回答”了 here,但没有任何代码来表明他们做了不同的事情,我不得不问一个新问题.

我有自己的代码具有相同的行为,在OS X上使用Core Bluetooth的CBCentralManager扫描特定的CBUUID并没有发现一个iOS设备充当CBPeripheralManager的外围设备(除非它及其服务先前已被发现).为了查看我的代码是否有问题,我下载了Apple’s sample code.在两台iOS设备上运行示例代码按预期工作,但是当将CBCentralManager代码复制到OS X应用程序时,它无法找到iOS设备.

我已经为OS X应用程序上传了一个Xcode项目,它是hosted on WikiUpload,因为它似乎是最不狡猾的.如果人们愿意,还有a copy on my hosting.

这是OS X项目中的AppDelegate.m代码(CoreBluetooth框架在项目中链接):

#import <CoreBluetooth/CoreBluetooth.h>@interface AppDelegate () <CBCentralManagerDelegate,CBPeripheralDelegate>@property (strong,nonatomic) CBCentralManager      *centralManager;@property (strong,nonatomic) CBPeripheral          *discoveredPeripheral;@property (strong,nonatomic) NSMutableData         *data;@property (weak) IBOutlet NSWindow *window;@end@implementation AppDelegate@synthesize centralManager = _centralManager,discoveredPeripheral = _discoveredPeripheral,data = _data;- (voID)applicationDIDFinishLaunching:(NSNotification *)aNotification {    // Insert code here to initialize your application    // Start up the CBCentralManager    _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];    // And somewhere to store the incoming data    _data = [[NSMutableData alloc] init];}- (voID)applicationWillTerminate:(NSNotification *)aNotification {    // Insert code here to tear down your application}#pragma mark - Central Methods/** centralManagerDIDUpdateState is a required protocol method. *  Usually,you'd check for other states to make sure the current device supports LE,is powered on,etc. *  In this instance,we're just using it to wait for CBCentralManagerStatePoweredOn,which indicates *  the Central is ready to be used. */- (voID)centralManagerDIDUpdateState:(CBCentralManager *)central{    if (central.state != CBCentralManagerStatePoweredOn) {        // In a real app,you'd deal with all the states correctly        return;    }    // The state must be CBCentralManagerStatePoweredOn...    // ... so start scanning    [self scan];}/** Scan for peripherals - specifically for our service's 128bit CBUUID */- (voID)scan{    // This brings up nothing,unlike on iOS where it finds the device straight away    [self.centralManager scanForperipheralsWithServices:@[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]                                                options:@{ CBCentralManagerScanoptionAllowDuplicatesKey : @YES }];//    [self.centralManager scanForperipheralsWithServices:nil//                                                options:@{ CBCentralManagerScanoptionAllowDuplicatesKey : @YES }];    NSLog(@"Scanning started");}/** This callback comes whenever a peripheral that is advertising the TRANSFER_SERVICE_UUID is discovered. *  We check the RSSI,to make sure it's close enough that we're interested in it,and if it is,*  we start the connection process */- (voID)centralManager:(CBCentralManager *)central dIDdiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{    NSLog(@"discovered %@ at %@",peripheral.name,RSSI);    //Took out RSSI check    if (self.discoveredPeripheral != peripheral) {        // Save a local copy of the peripheral,so CoreBluetooth doesn't get rID of it        self.discoveredPeripheral = peripheral;        // And connect        NSLog(@"Connecting to peripheral %@",peripheral);        [self.centralManager connectPeripheral:peripheral options:nil];    }}/** If the connection fails for whatever reason,we need to deal with it. */- (voID)centralManager:(CBCentralManager *)central dIDFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{    NSLog(@"Failed to connect to %@. (%@)",peripheral,[error localizedDescription]);    [self cleanup];}/** We've connected to the peripheral,Now we need to discover the services and characteristics to find the 'transfer' characteristic. */- (voID)centralManager:(CBCentralManager *)central dIDConnectPeripheral:(CBPeripheral *)peripheral{    NSLog(@"Peripheral Connected");    // Stop scanning    [self.centralManager stopScan];    NSLog(@"Scanning stopped");    // Clear the data that we may already have    [self.data setLength:0];    // Make sure we get the discovery callbacks    peripheral.delegate = self;    // Search only for services that match our UUID    [peripheral discoverServices:@[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]];}/** The Transfer Service was discovered */- (voID)peripheral:(CBPeripheral *)peripheral dIDdiscoverServices:(NSError *)error{    if (error) {        NSLog(@"Error discovering services: %@",[error localizedDescription]);        [self cleanup];        return;    }    // discover the characteristic we want...    // Loop through the newly filled peripheral.services array,just in case there's more than one.    for (CBService *service in peripheral.services) {        [peripheral discovercharacteristics:@[[CBUUID UUIDWithString:TRANSFER_CHaraCTERISTIC_UUID]] forService:service];    }}/** The Transfer characteristic was discovered. *  Once this has been found,we want to subscribe to it,which lets the peripheral kNow we want the data it contains */- (voID)peripheral:(CBPeripheral *)peripheral dIDdiscovercharacteristicsForService:(CBService *)service error:(NSError *)error{    // Deal with errors (if any)    if (error) {        NSLog(@"Error discovering characteristics: %@",[error localizedDescription]);        [self cleanup];        return;    }    // Again,we loop through the array,just in case.    for (CBCharacteristic *characteristic in service.characteristics) {        // And check if it's the right one        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHaraCTERISTIC_UUID]]) {            // If it is,subscribe to it            [peripheral setNotifyValue:YES forCharacteristic:characteristic];        }    }    // Once this is complete,we just need to wait for the data to come in.}/** This callback lets us kNow more data has arrived via notification on the characteristic */- (voID)peripheral:(CBPeripheral *)peripheral dIDUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{    if (error) {        NSLog(@"Error discovering characteristics: %@",[error localizedDescription]);        return;    }    Nsstring *stringFromData = [[Nsstring alloc] initWithData:characteristic.value enCoding:NSUTF8StringEnCoding];    // Have we got everything we need?    if ([stringFromData isEqualToString:@"EOM"]) {        // We have,so show the data,//[self.textvIEw setText:[[Nsstring alloc] initWithData:self.data enCoding:NSUTF8StringEnCoding]];        NSLog(@"Text: %@",[[Nsstring alloc] initWithData:self.data enCoding:NSUTF8StringEnCoding]);        // Cancel our subscription to the characteristic        [peripheral setNotifyValue:NO forCharacteristic:characteristic];        // and disconnect from the peripehral        [self.centralManager cancelPeripheralConnection:peripheral];    }    // Otherwise,just add the data on to what we already have    [self.data appendData:characteristic.value];    // Log it    NSLog(@"Received: %@",stringFromData);}/** The peripheral letting us kNow whether our subscribe/unsubscribe happened or not */- (voID)peripheral:(CBPeripheral *)peripheral dIDUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{    if (error) {        NSLog(@"Error changing notification state: %@",error.localizedDescription);    }    // Exit if it's not the transfer characteristic    if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHaraCTERISTIC_UUID]]) {        return;    }    // Notification has started    if (characteristic.isnotifying) {        NSLog(@"Notification began on %@",characteristic);    }    // Notification has stopped    else {        // so disconnect from the peripheral        NSLog(@"Notification stopped on %@.  disconnecting",characteristic);        [self.centralManager cancelPeripheralConnection:peripheral];    }}/** Once the disconnection happens,we need to clean up our local copy of the peripheral */- (voID)centralManager:(CBCentralManager *)central dIDdisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{    NSLog(@"Peripheral disconnected");    self.discoveredPeripheral = nil;    // We're disconnected,so start scanning again    [self scan];}/** Call this when things either go wrong,or you're done with the connection. *  This cancels any subscriptions if there are any,or straight disconnects if not. *  (dIDUpdateNotificationStateForCharacteristic will cancel the connection if a subscription is involved) */- (voID)cleanup{    // Don't do anything if we're not connected    if (!self.discoveredPeripheral.isConnected) {        return;    }    // See if we are subscribed to a characteristic on the peripheral    if (self.discoveredPeripheral.services != nil) {        for (CBService *service in self.discoveredPeripheral.services) {            if (service.characteristics != nil) {                for (CBCharacteristic *characteristic in service.characteristics) {                    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHaraCTERISTIC_UUID]]) {                        if (characteristic.isnotifying) {                            // It is notifying,so unsubscribe                            [self.discoveredPeripheral setNotifyValue:NO forCharacteristic:characteristic];                            // And we're done.                            return;                        }                    }                }            }        }    }    // If we've got this far,we're connected,but we're not subscribed,so we just disconnect    [self.centralManager cancelPeripheralConnection:self.discoveredPeripheral];}

在AppDelegate.h中有UUID定义:

#ifndef LE_Transfer_TransferService_h#define LE_Transfer_TransferService_h#define TRANSFER_SERVICE_UUID           @"E20A39F4-73F5-4BC4-A12F-17D1AD07A961"#define TRANSFER_CHaraCTERISTIC_UUID    @"08590F7E-DB05-467E-8757-72F6FAEB13D4"#endif

这有什么问题?根据上面的链接问题,服务必须是广告包的一部分,但据我所知,这正是iOS外设正在做的事情

[self.peripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] }];
解决方法 CoreBluetooth可能非常令人沮丧.这里有几件事要尝试:

#1:已连接的外围设备停止广告.如果您成功连接到外围设备,则需要重新开始广告.

#2:iOS缓存已发现状态和提供的服务.没有编程方式来刷新/清除缓存.尝试在iOS设备和Mac上禁用BT并重新启用它.然后尝试另一个连接.

#3:您的UUID存在问题.尝试扫描UUID参数设置为nil的外围设备.然后,您应该发现范围内的所有外围设备.

#4:如果Wifi打开,Mac上的BT连接可能很挑剔.尝试在Mac上禁用Wifi,然后重试.我发现BTLE在启用Wifi时完全无法使用,因此我在MacBook上执行任何BTLE开发时都必须使用以太网.

总结

以上是内存溢出为你收集整理的ios – 扫描特定CBUUID时,Core Bluetooth无法找到外围设备全部内容,希望文章能够帮你解决ios – 扫描特定CBUUID时,Core Bluetooth无法找到外围设备所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1107604.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存