#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, у нас все хорошо!