Подключиться к периферии в didSelectRowAtIndexPath

Я разрабатываю приложение, используя CoreBluetooth. Я могу обнаруживать устройства из приложения и отображать их имена в виде таблицы. Я столкнулся с проблемой с требованиями ниже:

  • При первом использовании пользователь выбирает периферийное устройство из списка. Соединение с периферийным устройством должно быть установлено с использованием профиля последовательного порта Bluetooth (SPP). Обнаружение и подключение выполняются простым щелчком мыши, что сводит к минимуму взаимодействие с пользователем.
  • Как только соединение между периферийным устройством и приложением установлено, приложение запоминает устройство и всегда ищет его и подключается к нему для всех последующих использований.

Я написал для этого следующий код, как показано ниже, для сканирования и обнаружения

- (void)scan
{
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
    NSLog(@"options are %@",options);

    [self.centralManager scanForPeripheralsWithServices:nil
                                                options:nil];
    _txtLogMessage.text = [NSString stringWithFormat:@"%@ \n %@",_txtLogMessage.text,@"Scanning started"];
    NSLog(@"Scanning started");
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral
                                                                          *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    [central connectPeripheral:peripheral options:nil];
    self.discoveredPeripheral = peripheral;
    _logData = [NSString stringWithFormat:@"Did discover peripheral. peripheral: %@ rssi: %@, UUID: %@   advertisementData: %@ ", peripheral, RSSI, peripheral.UUID, advertisementData];

    NSLog(@"%@",_logData);


    [_periferalDevices addObject:peripheral.name];
    [_tableView reloadData];
}

для подключения устройства

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    peripheral.delegate = self;

    [self.discoveredPeripheral discoverServices:nil];
    NSLog(@"Peripheral Connected");
    NSLog(@" started  time is %@",_timestring);

    //[self.centralManager stopScan];
    NSLog(@"Scanning stopped");
    [self.data setLength:0];

    [peripheral discoverServices:nil];

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

в ячейке представления таблицы для строки в пути индекса цель может получить данные для просмотра, но цель - столкнуться с проблемой подключения к периферийному устройству, когда конкретная строка выбрана в представлении таблицы

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:CellIdentifier];
    }
    cell.textLabel.text = [_periferalDevices objectAtIndex:indexPath.row];

    return  cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    _discoveredPeripheral.delegate = self;
    [self.centralManager connectPeripheral:[_periferalDevices objectAtIndex:indexPath.row]
                                   options:nil];
    NSLog(@"discovered peripheral is %@",[_periferalDevices objectAtIndex:indexPath.row]);
    NSString *datstr=[_discoveredPeripheral valueForKey:@"identifier"];
    NSLog(@"value for key is ........%@",datstr);
}

person iosdeveloper    schedule 14.10.2014    source источник
comment
Обычно вы не должны извлекать необходимую информацию из ячейки, но должны получить доступ к своему источнику данных для получения информации.   -  person Hot Licks    schedule 14.10.2014
comment
я использую [self.centralManager connectPeripheral: [_periferalDevices objectAtIndex: indexPath.row] параметры: ноль]; NSLog(@обнаруженное периферийное устройство равно %@,[_periferalDevices objectAtIndex:indexPath.row]); но все еще сталкиваюсь с ошибкой   -  person iosdeveloper    schedule 14.10.2014


Ответы (1)


Ошибки, которые вы получаете, когда пытаетесь использовать периферийный объект, связаны с тем, что вы добавили имя периферийного устройства в свой массив, а не само периферийное устройство. Таким образом, заменить

[_periferalDevices addObject:peripheral.name]; 

С

[_periferalDevices addObject:peripheral];

И, очевидно, вам придется исправить везде, где вы воспользовались простой вставкой имени. Например, ваш cellForRowAtIndexPath содержит строку, которая гласит:

cell.textLabel.text = [_periferalDevices objectAtIndex:indexPath.row];

Вы, вероятно, захотите заменить это чем-то вроде:

CBPeripheral *peripheral = _periferalDevices[indexPath.row];
cell.textLabel.text = peripheral.name;

Ваш didDiscover... немедленно подключается. Наверное, не должно. Вероятно, вам следует попробовать подключиться только к устройству, выбранному пользователем. Это может вызвать проблемы, если вы попытаетесь подключиться снова (я не знаю, что произойдет, если вы попытаетесь подключиться дважды). Ваш didSelectRow... подключается к тем, которые выбирает пользователь, поэтому вам, вероятно, следует оставить это как есть.

Вы говорите: «Сталкиваюсь с проблемой подключения». Итак, что именно сообщил didFailToConnectPeripheral?

Кроме того, мне непонятно, почему вы звоните discoverServices дважды. Либо откройте все службы (медленно), либо откройте только конкретную службу, но вам, вероятно, не нужно делать и то, и другое.


Мой первоначальный ответ (основанный на исходном образце кода) приведен ниже.


У вас есть код, который говорит:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    NSString *cellText = cell.textLabel.text;

    if([cellText isEqualToString:@""])
    {

    }
    else
    {
        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Connected to "
                                                      message:cellText delegate:self cancelButtonTitle:@"ok"
                                            otherButtonTitles: nil];
        [alert show];
    }

    _discoveredPeripheral.delegate = self;
    [self.centralManager connectPeripheral:_discoveredPeripheral options:nil];
    NSLog(@"discovered peripheral is %@", _discoveredPeripheral);
    NSString *datstr = [_discoveredPeripheral valueForKey:@"identifier"];
    NSLog(@"value for key is ........%@", datstr);
}

Вы извлекаете информацию о выбранной ячейке (хотя Hot Licks верны, вы должны обращаться к своей модели, а не к представлению для получения этой информации), извлекаете cellText, но продолжаете использовать _discoveredPeripheral, которая представляет собой некоторую переменную, которая несет нет очевидной связи с ячейкой, которую только что выбрал пользователь.

Вы хотите сохранить свою модель массива периферийных устройств, и когда пользователь нажимает на ячейку, используйте indexPath.row для поиска периферийного устройства в массиве вашей модели и используйте этот CBPeripheral в коде подключения.

person Rob    schedule 14.10.2014
comment
я дал массив периферийных устройств, то есть такой же, как в ячейке для строки в индексном пути, чтобы выбрать строку [self.centralManager connectPeripheral: [_periferalDevices objectAtIndex: indexPath.row] options: nil]; даже я обнаружил ошибку типа [__NSCFString идентификатор]: нераспознанный селектор отправлен экземпляру 0x15637f50 2014-10-14 10:56:48.839 Bluetooth_iph[1696:364445] *** Завершение работы приложения из-за неперехваченного исключения 'NSInvalidArgumentException', причина: '- [__NSCFString идентификатор]: нераспознанный селектор отправлен экземпляру 0x15637f50' - person iosdeveloper; 14.10.2014
comment
@iosdeveloper - не пытайтесь получить identifier из NSString. - person Hot Licks; 14.10.2014
comment
@iosdeveloper Это связано с тем, что вы сделали [_periferalDevices addObject:peripheral.name];, а не [_periferalDevices addObject:peripheral];. Вы только что добавили имя периферийного устройства в свой массив, но на самом деле хотите добавить сам периферийный объект. - person Rob; 14.10.2014