Последующие обратные вызовы из плагина Cordova iOS не срабатывают

У меня проблемы с запуском сразу же последующих обратных вызовов из плагина Cordova (для iOS). В отладчике XCode я ясно вижу, что он перешагивает

[self.commandDelegate sendPluginResult:pluginResult callbackId:monitoredRegions.callbackId];

несколько раз (в непосредственной последовательности), каждый раз с немного другим pluginResult. Это вызывается

[locationManager requestStateForRegion:region];

которые я не контролирую (и не могу) контролировать.

Проблема в том, что на стороне Javascript обратный вызов запускается только один раз.

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

Насколько я понимаю, commandDelegate должен заботиться о многопоточности и очередях, но похоже, что это не так. Вопрос в том, как запустить обратный вызов JS каждый раз, когда вызывается sendPluginResult.

Большое спасибо!


person meandre    schedule 16.07.2014    source источник


Ответы (1)


Итак, проблема была не в многопоточности/очереди.

Оказалось, что вам разрешено использовать callbackId только один раз, если вы не скажете Cordova не очищать этот callbackId, установив CDVPluginResult.keepCallback в true. Обратите внимание, что keepCallback не является свойством BOOL, поэтому вам может понадобиться вызвать [pluginResult setKeepCallbackAsBool:YES];

CDVPluginResult* pluginResult = [sendPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:key];
[pluginResult setKeepCallbackAsBool:YES]; // here we tell Cordova not to cleanup the callback id after sendPluginResult()
[self.commandDelegate sendPluginResult:pluginResult callbackId:monitoredRegions.callbackId];

Все портит то, что если вы введете блокирующий вызов, такой как alert() в этом обратном вызове, Cordova позволит вам сделать несколько последовательных sendPluginResult с одним и тем же callbackId.

Имейте в виду, что вам может понадобиться sendPluginResult с CDVPluginResult, который keepCallback равен false, чтобы освободить callbackId, который вам больше не нужен.

person meandre    schedule 17.07.2014
comment
Спасибо за объяснение того, что делает setKeepCallback. Я ломал голову над этим сценарием. - person mpoisot; 22.03.2016
comment
У меня был pluginResult.keepCallback = [NSNumber numberWithBool:YES]; и он просто не работал. Я изменил его на [pluginResult setKeepCallbackAsBool:YES];, и это волшебным образом сработало! - person solidak; 20.02.2018
comment
Спасибо @meandre, у меня была такая же проблема - person sebba23; 14.02.2020