【问题标题】:IOS Bluetooth LE Scanning Devices not adding to the uitableviewIOS 蓝牙 LE 扫描设备未添加到 uitableview
【发布时间】:2014-07-11 08:24:18
【问题描述】:

我想使用uitableview实现IOS的蓝牙扫描和连接模块。在执行方面,没有项目被添加到列表中。你能告诉我我还需要做什么来显示带有设备名称、uuid 等的蓝牙设备列表吗?

例如, 1.如何将我的对象数组设置为uitableview的数据源? 2. 点击时如何处理设备之间的蓝牙连接?

 _currentperipheral = peripheral; <--also fails at Thread 1 EXC_BREAKPOINT

以下是我的控制台消息

  2014-07-11 16:34:18.286 marker[6060:60b] Scanning started
2014-07-11 17:53:14.056 marker[6115:60b] Discovered WiT Power Meter at -67

下面是我的模型类:

@interface BTDevice : NSObject {
    NSString *name;
    NSString *macAddress;
}


@property(nonatomic, retain) NSString *name;
@property(nonatomic, retain) NSString *macAddress;

- (NSString *)getName;
- (NSString *)getMacAddress;

- (void)setName:(NSString *)valueName;
- (void)setMacAddress:(NSString *)valueMacAddress;

@end

以下是我的工作:

- (void)viewDidLoad
{
    [super viewDidLoad];

    _pendingInit = YES;

    _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
    _currentperipheral=[[CBPeripheral alloc]init];
    _founddevice=FALSE;
    _foundPeripherals = [[NSMutableArray alloc] init];
    _connectedServices = [[NSMutableArray alloc] init];

}

- (void)viewWillDisappear:(BOOL)animated {

    [_centralManager stopScan];
    NSLog(@"Scanning stopped");
    [super viewWillDisappear:animated];
}


#pragma mark - Table view data source

- (void)tableView: (UITableView *)tableView
didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
    int idx=indexPath.row;
    BTSentCommandViewController * sliderVC = [self.storyboard instantiateViewControllerWithIdentifier:@"BTSentCommandViewController"];
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return  [_foundPeripherals count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return [_foundPeripherals count];
}



- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    // You should test all scenarios
    if (central.state != CBCentralManagerStatePoweredOn) {
        return;
    }

    if (central.state == CBCentralManagerStatePoweredOn) {
        // Scan for devices

        [_centralManager scanForPeripheralsWithServices:nil options:nil];
        NSLog(@"Scanning started");
    }
}


- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {

    NSLog(@"Discovered %@ at %@", peripheral.name, RSSI);

    if (_currentperipheral != peripheral) {
        // Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it
        _currentperipheral = peripheral;

        BTDevice *myDevice=[[BTDevice alloc] init];
        [myDevice setName: peripheral.name];

        NSString * macAddress =   [NSString stringWithFormat:@"%@" , peripheral.RSSI];
        [myDevice setMacAddress: macAddress] ;

        [_foundPeripherals addObject:myDevice ] ;

         [self.tableView reloadData];   
        NSLog(@"Connecting to peripheral %@", peripheral);
        [_centralManager connectPeripheral:peripheral options:nil];
    }
}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    NSLog(@"Failed to connect");
    [self cleanup];
}


- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    NSLog(@"Connected");

    [_centralManager stopScan];
    NSLog(@"Scanning stopped");

    peripheral.delegate = self;

    [peripheral discoverServices:@[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]];
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    if (error) {
        [self cleanup];
        return;
    }

    for (CBService *service in peripheral.services) {
        [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]] forService:service];
    }
    // Discover other characteristics
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    if (error) {
        [self cleanup];
        return;
    }

    for (CBCharacteristic *characteristic in service.characteristics) {
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
            [peripheral setNotifyValue:YES forCharacteristic:characteristic];
        }
    }
}


- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error) {
        NSLog(@"Error");
        return;
    }

    NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];

    if ([stringFromData isEqualToString:@"EOM"]) {


        [peripheral setNotifyValue:NO forCharacteristic:characteristic];

        [_centralManager cancelPeripheralConnection:peripheral];
    }

    //[_data appendData:characteristic.value];
}


- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {

    if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
        return;
    }

    if (characteristic.isNotifying) {
        NSLog(@"Notification began on %@", characteristic);
    } else {
        // Notification has stopped
        [_centralManager cancelPeripheralConnection:peripheral];
    }
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    _foundPeripherals = nil;

    [_centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
}

- (void)cleanup {

    // See if we are subscribed to a characteristic on the peripheral
    if (_currentperipheral.services != nil) {
        for (CBService *service in _currentperipheral.services) {
            if (service.characteristics != nil) {
                for (CBCharacteristic *characteristic in service.characteristics) {
                    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
                        if (characteristic.isNotifying) {
                            [_currentperipheral setNotifyValue:NO forCharacteristic:characteristic];
                            return;
                        }
                    }
                }
            }
        }
    }

    [_centralManager cancelPeripheralConnection:_currentperipheral];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}




- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];

    if (cell == nil) {
        cell =  [ [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"reuseIdentifier"] ;

        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }

    cell.textLabel.text = [_foundPeripherals objectAtIndex:indexPath.row];
    // Configure the cell...

    return cell;
}

【问题讨论】:

    标签: ios iphone objective-c uitableview bluetooth


    【解决方案1】:

    这里有很多代码,但总体看起来还可以。然而,有两件事很突出。您的 numberOfSectionsInTableView 返回 0 - 因此您的表格中将没有内容。你应该有 -

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        // Return the number of sections.
        return 1;
    }
    

    我建议您将 CBPeripheral 存储在您的数据数组中。

    此外,一旦你发现了一个外围设备并将其添加到你的数组中,你应该通知 table view 数据源已经更新(这个代码假设你有属性 tableView 包含对你的 tableview 的引用) -

    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    
        NSLog(@"Discovered %@ at %@", peripheral.name, RSSI);
    
        if (![_foundPeripherals containsObject:peripheral]) {
            [_foundPeripherals addObject:myDevice ] ;
    
            [self.tableView reloadData];     // Tell the tableview that the data source has changed
        }
    
    }
    

    那么你的cellForRowAtIndexPath就变成了-

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath];
    
        if (cell == nil) {
            cell =  [ [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"reuseIdentifier"] ;
    
    
            cell.selectionStyle = UITableViewCellSelectionStyleGray;
        }
    
    
        CBPeripheral *peripheral=[_foundPeripherals objectAtIndex:indexPath.row];
    
        cell.textLabel.text = peripheral.name; 
        // Configure the cell...
    
        return cell;
    }
    

    选择表格行时连接外围设备 -

    - (void)tableView: (UITableView *)tableView
    didSelectRowAtIndexPath: (NSIndexPath *)indexPath
    {
    
        [self performSegueWithIdentifier:@"connectSegue" sender:[_foundPeripherals objectAtIndex:indexPath.row]];  //  This is a segue to your BTSentCommandViewController
    }
    
    -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
    {
         BTSentCommandViewController* sliderVC=( BTSentCommandViewController *)segue.destinationViewController;
         sliderVC.centralManager=_centralManager;
         sliderVC.periperhal=_sender;
    
    }
    

    在您的BTSentCommandViewController 中,您可以连接到外围设备。您还应该将BTSentCommandViewController 实例设置为外围设备委托并在那里实现所有CBPeripheralDelegate 方法

    【讨论】:

    • 我使用了 LightBlue,因此检查了几个设备。至于我的应用程序,他们甚至都没有遵循你的工作。
    • 我必须通过prepareForSegue调用方法连接蓝牙的哪一部分?
    • 我会在 prepareForSegue 中将 CBPeripheral 传递给您的目标视图控制器,然后在 viewWillAppear 中连接它 - 但您可能应该从视图控制器中删除所有 CoreBluetooth 内容并将其放在单独的类 - 它会让你的视图控制器实现更干净
    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 2021-12-26
    • 2015-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多