Выполнение общих центральных ролевых задач

Устройства, реализующие центральную роль в низкоэнергетической коммуникации Bluetooth, выполняют много общих задач — например, обнаруживая и соединяясь с доступными периферийными устройствами, и исследуя и взаимодействуя с данными, которые должны предложить периферийные устройства. Напротив, устройства, реализующие периферийную роль также, выполняют много общих, но различных, задач — например, публикуя и рекламных услуг, и отвечая на чтение, пишут, и запросы подписки от связанного centrals.

В этой главе Вы изучите, как использовать Ядро платформа Bluetooth для выполнения наиболее распространенных типов низкоэнергетических задач Bluetooth с центральной стороны. Следующие основанные на коде примеры помогут Вам в разработке Вашего приложения реализовывать центральную роль на своем локальном устройстве. В частности Вы будете учиться как:

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

Примеры кода, которые Вы находите в этой главе, просты и абстрактны; Вы, возможно, должны внести надлежащие изменения для слияния их в приложение реального мира. Более усовершенствованные темы, связанные с реализацией центральной роли — включая подсказки, приемы и методы наиболее успешной практики — затронуты в более поздних главах, Ядро Фоновая обработка Bluetooth для приложений для iOS и Методы наиболее успешной практики для Взаимодействия с Удаленным Периферийным устройством.

Запуск центрального менеджера

С тех пор a CBCentralManager объектом является Ядро Bluetooth объектно-ориентированное представление локального центрального устройства, необходимо выделить и инициализировать центральный экземпляр менеджера, прежде чем можно будет выполнить любые низкоэнергетические транзакции Bluetooth. Можно запустить центрального менеджера путем вызова initWithDelegate:queue:options: метод CBCentralManager класс, как это:

    myCentralManager =
        [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];

В этом примере, self установлен как делегат получить любые центральные ролевые события. Путем указания очереди отгрузки как nil, центральный менеджер диспетчеризирует центральные ролевые события с помощью основной очереди.

Когда Вы создаете центрального менеджера, центральные вызовы диспетчера centralManagerDidUpdateState: метод его объекта делегата. Необходимо реализовать этот метод делегата гарантировать, что низкая энергия Bluetooth поддерживается и доступна для использования на центральном устройстве. Для получения дополнительной информации о том, как реализовать этот метод делегата, посмотрите Ссылку на протокол CBCentralManagerDelegate.

Обнаружение распространяющихся периферийных устройств

Одна из первых задач центральной стороны, которые Вы, вероятно, выполните, состоит в том, чтобы обнаружить то, с чем периферийные устройства доступны для Вашего приложения для соединения. Как отмечалось ранее, в Centrals Обнаруживают и Подключение к Периферийным устройствам, Распространяющимся, распространение является основным способом, которым периферийные устройства делают свое присутствие известным. Можно обнаружить любые периферийные устройства, распространяющиеся путем вызова scanForPeripheralsWithServices:options: метод CBCentralManager класс, как это:

    [myCentralManager scanForPeripheralsWithServices:nil options:nil];

После вызова scanForPeripheralsWithServices:options: метод для обнаружения, какие периферийные устройства доступны, центральные вызовы диспетчера centralManager:didDiscoverPeripheral:advertisementData:RSSI: метод его делегата возражает каждый раз, когда периферийное устройство обнаружено. Любое обнаруженное периферийное устройство возвращается как a CBPeripheral объект. Поскольку следующее показывает, можно реализовать этот метод делегата перечислить любое периферийное устройство, обнаруженное:

- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary *)advertisementData
                  RSSI:(NSNumber *)RSSI {
 
    NSLog(@"Discovered %@", peripheral.name);
    ...

При нахождении периферийного устройства, что Вы интересуетесь соединением с, прекращаете сканировать для других устройств для экономии электроэнергии.

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

Соединение с периферийным устройством после обнаружения его

После обнаружения периферийного устройства, которое является рекламными услугами, которыми Вы интересуетесь, можно запросить соединение с периферийным устройством путем вызова connectPeripheral:options: метод CBCentralManager класс. Просто вызовите этот метод и укажите обнаруженное периферийное устройство, которое Вы хотите подключить с, как это:

    [myCentralManager connectPeripheral:peripheral options:nil];

Предполагая, что запрос на установление соединения успешен, центральные вызовы диспетчера centralManager:didConnectPeripheral: метод его объекта делегата, который можно реализовать для журналирования этого соединение, установлен, поскольку следующее показывает:

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

Прежде чем Вы начнете взаимодействовать с периферийным устройством, необходимо установить делегата периферийного устройства, чтобы гарантировать, что оно получает надлежащие обратные вызовы, как это:

    peripheral.delegate = self;

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

После установления соединения с периферийным устройством можно начать исследовать его данные. Первый шаг в исследовании, что должно предложить периферийное устройство, обнаруживает свои доступные службы. Поскольку существуют ограничения размера на объем данных, который может распространить периферийное устройство, можно обнаружить, что периферийное устройство имеет больше служб, чем, что это распространяет (в его рекламных пакетах). Можно обнаружить все услуги, которые периферийное устройство предлагает путем вызова discoverServices: метод CBPeripheral класс, как это:

    [peripheral discoverServices:nil];

Когда указанные службы обнаружены, периферийное устройство ( CBPeripheral объект, с которым Вы подключены) вызывает peripheral:didDiscoverServices: метод его объекта делегата. Базовый Bluetooth создает массив CBService объекты — один для каждой службы, обнаруженной на периферийном устройстве. Поскольку следующее показывает, можно реализовать этот метод делегата получить доступ к массиву обнаруженных служб:

- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error {
 
    for (CBService *service in peripheral.services) {
        NSLog(@"Discovered service %@", service);
        ...
    }
    ...

Обнаружение характеристик службы

Предположение, что Вы нашли службу, которой Вы интересуетесь, следующий шаг в исследовании, что должно предложить периферийное устройство, обнаруживает все характеристики службы. Обнаружение всех характеристик службы так же просто как вызов discoverCharacteristics:forService: метод CBPeripheral класс, указывая надлежащую службу, как это:

    NSLog(@"Discovering characteristics for service %@", interestingService);
    [peripheral discoverCharacteristics:nil forService:interestingService];

Периферийное устройство вызывает peripheral:didDiscoverCharacteristicsForService:error: когда характеристики указанной службы обнаружены, метод его делегата возражает. Базовый Bluetooth создает массив CBCharacteristic объекты — один для каждой обнаруженной характеристики. Следующий пример показывает, как можно реализовать этот метод делегата просто зарегистрировать каждую характеристику, обнаруженную:

- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
             error:(NSError *)error {
 
    for (CBCharacteristic *characteristic in service.characteristics) {
        NSLog(@"Discovered characteristic %@", characteristic);
        ...
    }
    ...

Получение значения характеристики

Характеристика содержит единственное значение, представляющее больше информации о службе периферийного устройства. Например, характеристика измерения температуры медицинской службы термометра может иметь значение, указывающее температуру в Цельсия. Можно получить значение характеристики путем чтения его непосредственно или путем подписки на него.

Чтение значения характеристики

После нахождения характеристики службы, которой Вы интересуетесь, можно считать значение характеристики путем вызова readValueForCharacteristic: метод CBPeripheral класс, указывая надлежащую характеристику, как это:

    NSLog(@"Reading value for characteristic %@", interestingCharacteristic);
    [peripheral readValueForCharacteristic:interestingCharacteristic];

Когда Вы пытаетесь считать значение характеристики, периферийное устройство вызывает peripheral:didUpdateValueForCharacteristic:error: метод его делегата возражает для получения значения. Если значение успешно получено, можно получить доступ к нему через свойство значения характеристики, как это:

- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
             error:(NSError *)error {
 
    NSData *data = characteristic.value;
    // parse the data as needed
    ...

Подписка на значение характеристики

Хотя читая значение характеристики с помощью readValueForCharacteristic: метод может быть эффективным для некоторых вариантов использования, это не самый эффективный способ получить изменяющееся значение. Для наиболее характеристических значений, изменяющихся — например, Ваш сердечный ритм в любой момент времени — необходимо получить их путем подписки на них. Когда Вы подписываетесь на значение характеристики, Вы получаете уведомление от периферийного устройства, когда изменяется значение.

Можно подписаться на значение характеристики, что Вы интересуетесь путем вызова setNotifyValue:forCharacteristic: метод CBPeripheral класс, указывая первый параметр как YES, как это:

    [peripheral setNotifyValue:YES forCharacteristic:interestingCharacteristic];

Когда Вы пытаетесь подписаться (или отписаться) к значению характеристики, периферийное устройство вызывает peripheral:didUpdateNotificationStateForCharacteristic:error: метод его объекта делегата. Если запрос подписки перестал работать по какой-либо причине, можно реализовать этот метод делегата получить доступ к причине ошибки, поскольку следующий пример показывает:

- (void)peripheral:(CBPeripheral *)peripheral
didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic
             error:(NSError *)error {
 
    if (error) {
        NSLog(@"Error changing notification state: %@",
           [error localizedDescription]);
    }
    ...

Когда значение изменилось, после успешной подписки на значение характеристики периферийное устройство уведомляет приложение. Каждый раз изменения значения, периферийное устройство вызывает peripheral:didUpdateValueForCharacteristic:error: метод его объекта делегата. Для получения обновленного значения можно реализовать этот метод таким же образом, как описано выше в Чтении Значения Характеристики.

Запись значения характеристики

Для некоторых вариантов использования это целесообразно писать значение характеристики. Например, если Ваше приложение взаимодействует с низкой энергией Bluetooth цифровой термостат, можно хотеть предоставить термостату значение, в котором можно установить температуру комнаты. Если значение характеристики writeable, можно записать его значение с некоторыми данными (экземпляр NSData) путем вызова writeValue:forCharacteristic:type: метод CBPeripheral класс, как это:

    NSLog(@"Writing value for characteristic %@", interestingCharacteristic);
    [peripheral writeValue:dataToWrite forCharacteristic:interestingCharacteristic
        type:CBCharacteristicWriteWithResponse];

Когда Вы пытаетесь записать значение характеристики, Вы указываете, какую запись Вы хотите выполнить. В примере выше, тип записи указан как CBCharacteristicWriteWithResponse, который указывает, что периферийное устройство сообщает Вашему приложению, успешна ли запись. Для получения дополнительной информации о типах записи, поддерживающихся в Ядре платформа Bluetooth, посмотрите CBCharacteristicWriteType перечисление в Ссылке класса CBPeripheral.

Периферийное устройство реагирует на запросы записи, указанные как CBCharacteristicWriteWithResponse путем вызова peripheral:didWriteValueForCharacteristic:error: метод его объекта делегата. Если запись перестала работать по какой-либо причине, можно реализовать этот метод делегата получить доступ к причине ошибки, поскольку следующий пример показывает:

- (void)peripheral:(CBPeripheral *)peripheral
didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
             error:(NSError *)error {
 
    if (error) {
        NSLog(@"Error writing characteristic value: %@",
            [error localizedDescription]);
    }
    ...