Диалоговое окно сопряжения iOS bluetooth «съедено» вызовом dispatch_sync

#ios #objective-c #multithreading #flutter #bluetooth

#iOS #objective-c #многопоточность #флаттер #bluetooth

Вопрос:

У меня интересная проблема. Я работаю над библиотекой BTLE и натыкаюсь на старую стену диалога сопряжения iOS BT.. Самое приятное, что у меня есть полностью функционирующее решение в небольшой демонстрации iOS. В указанной демонстрации все работает так, как и ожидалось, мы обращаемся к диалоговому окну сопряжения BT и видим выбор пользователя «Сопряжение» или «Отмена». После нашего вызова «connect» у нас есть желаемое состояние соединения, основанное на взаимодействии с пользователем. Однако при окончательной интеграции с приложением Flutter мы запускаем вызов connect в фоновой задаче (я полагаю, что действующая демонстрация находится в основном потоке), и диалоговое окно сопряжения BT никогда не отображается пользователю.. Примечание. если я использую закомментированный подход «dispatch_async», я действительно получаю диалоговое окно, но подключенное состояние всегда возвращает false, поскольку выполнение возвращается и завершается до того, как пользователь завершит диалог.

 if([@"connect2Device" isEqualToString:call.method]) {
        NSString *mac_Address = call.arguments[@"address"];
        //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_sync(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
            
            BleConnection connection;
            
            @try {
            connection = [self->ConnectionController connect: mac_Address];
            } @catch(NSException *exception) {
            result([FlutterError errorWithCode: exception.name message: exception.reason details:exception.userInfo]);
            }
            if(connection != nil) {
                if (connection.isConnected == true) {
                    NSLog(@"connection is true, returning YES from plugin");
                    result(@YES);
                } else {
                    NSLog(@"connection is true, returning NO from plugin");
                    result(@NO);
                }
            }
        });
    }
 

Есть какие-нибудь идеи относительно того, почему диалоговое окно скрыто вызовом dispatch_sycn? Я пробовал использовать все определенные типы очередей.. Из того, что я читаю, пока вы записываете зашифрованную характеристику, iOS автоматически запрашивает пользователя в этом диалоговом окне, никакого «реального» кода не требуется. Я думаю, что я знаком с этим подходом, поскольку именно так я в конечном итоге определяю, какой выбор сделал пользователь (через WriteWithNotify).

Комментарии:

1. Почему вы dispatch_sync все равно используете a? Операции записи BLE являются асинхронными. Вы не должны пытаться сделать их синхронными. Вам необходимо использовать обработчик завершения, метод обратного вызова или делегирования.

2. @Paul11 — спасибо за ответ. Я новичок в iOS / objective-c и BT 🙂 поэтому я, по сути, пытаюсь разобраться во всем этом сам. По моим наблюдениям, я использую dispatch_sync b / c только с точки зрения моих наблюдений, использование этого метода приводит к блокировке ConnectionController connect () до завершения (поэтому connect не возвращается немедленно, чего я и хочу, он должен «подключаться» в течение 30 секунд, чтобы позволить пользователю подтвердить диалоговое окно сопряжения. Если я использую dispatch_async, я вижу диалоговое окно сопряжения, но connect возвращается сразу после вызова. Я собираюсь протестировать новый impl для кода подключения, я буду держать вас в курсе

3. Это ваша проблема. Такого рода функции не могут «возвращать» значение. Операция является асинхронной. programmingios.net/what-asynchronous-means . Это очень распространенная парадигма в мобильной разработке. Я никогда не работал с flutter, но у него должен быть какой-то способ справиться с этим

4. Спасибо за разъяснения! В конечном итоге пришлось изменить то, что происходило на стороне библиотеки BTLE в открытом вызове… СПЯЩИЙ РЕБЕНОК СПИТ, пока мы не увидим символ уведомления, связанный с выбором диалога сопряжения. Действительно ценю быстрые ответы @Paul11, у нас все хорошо!