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

似乎这个问题被“回答”了 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开发时都必须使用以太网.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple 最新软件的错误和性能问题。
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只有5%的概率会遇到选择运营商界面且部分必须连接到iTunes才可以激活
一般在接外包的时候, 通常第三方需要安装你的app进行测试(这时候你的app肯定是还没传到app store之前)。
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应用变灰了。那么接下来我们看一下Flutter是如何实现的。Flutter中实现整个App变为灰色在Flutter中实现整个App变为灰色是非常简单的,只需要在最外层的控件上包裹ColorFiltered,用法如下:ColorFiltered(颜色过滤器)看名字就知道是增加颜色滤镜效果的,ColorFiltered( colorFilter:ColorFilter.mode(Colors.grey, BlendMode.
flutter升级/版本切换
(1)在C++11标准时,open函数的文件路径可以传char指针也可以传string指针,而在C++98标准,open函数的文件路径只能传char指针;(2)open函数的第二个参数是打开文件的模式,从函数定义可以看出,如果调用open函数时省略mode模式参数,则默认按照可读可写(ios_base:in | ios_base::out)的方式打开;(3)打开文件时的mode的模式是从内存的角度来定义的,比如:in表示可读,就是从文件读数据往内存读写;out表示可写,就是把内存数据写到文件中;
文章目录方法一:分别将图片和文字置灰UIImage转成灰度图UIColor转成灰度颜色方法二:给App整体添加灰色滤镜参考App页面置灰,本质是将彩色图像转换为灰度图像,本文提供两种方法实现,一种是App整体置灰,一种是单个页面置灰,可结合具体的业务场景使用。方法一:分别将图片和文字置灰一般情况下,App页面的颜色深度是24bit,也就是RGB各8bit;如果算上Alpha通道的话就是32bit,RGBA(或者ARGB)各8bit。灰度图像的颜色深度是8bit,这8bit表示的颜色不是彩色,而是256
领导让调研下黑(灰)白化实现方案,自己调研了两天,根据网上资料,做下记录只是学习过程中的记录,还是写作者牛逼
让学前端不再害怕英语单词(二),通过本文,可以对css,js和es6的单词进行了在逻辑上和联想上的记忆,让初学者更快的上手前端代码
用Python送你一颗跳动的爱心
在uni-app项目中实现人脸识别,既使用uni-app中的live-pusher开启摄像头,创建直播推流。通过快照截取和压缩图片,以base64格式发往后端。
商户APP调用微信提供的SDK调用微信支付模块,商户APP会跳转到微信中完成支付,支付完后跳回到商户APP内,最后展示支付结果。CSDN前端领域优质创作者,资深前端开发工程师,专注前端开发,在CSDN总结工作中遇到的问题或者问题解决方法以及对新技术的分享,欢迎咨询交流,共同学习。),验证通过打开选择支付方式弹窗页面,选择微信支付或者支付宝支付;4.可取消支付,放弃支付会返回会员页面,页面提示支付取消;2.判断支付方式,如果是1,则是微信支付方式。1.判断是否在微信内支付,需要在微信外支付。
Mac命令行修改ipa并重新签名打包
首先在 iOS 设备中打开开发者模式。位于:设置 - 隐私&安全 - 开发者模式(需重启)
一 现象导入MBProgressHUD显示信息时,出现如下异常现象Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_MBProgressHUD", referenced from: objc-class-ref in ViewController.old: symbol(s) not found for architecture x86_64clang: error: linker command failed wit
Profiles >> 加号添加 >> Distribution >> "App Store" >> 选择 2.1 创建的App ID >> 选择绑定 2.3 的发布证书(.cer)>> 输入描述文件名称 >> Generate 生成描述文件 >> Download。Certificates >> 加号添加 >> "App Store and Ad Hoc" >> “Choose File...” >> 选择上一步生成的证书请求文件 >> Continue >> Download。
今天有需求,要实现的功能大致如下:在安卓和ios端实现分享功能可以分享链接,图片,文字,视频,文件,等欢迎大佬多多来给萌新指正,欢迎大家来共同探讨。如果各位看官觉得文章有点点帮助,跪求各位给点个“一键三连”,谢啦~声明:本博文章若非特殊注明皆为原创原文链接。