Незаконный обратный вызов из собственного модуля для React Native Module с использованием Native SDK Framework с шаблоном делегирования - PullRequest
0 голосов
/ 28 апреля 2020

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

RNMYModuleBridge.m

//rndemo RNMyModule.m

#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(RNMyModule, NSObject)


RCT_EXTERN_METHOD(initializeBLESDK:
                      resolver:(RCTPromiseResolveBlock)resolve
                      rejecter:(RCTPromiseRejectBlock)reject
                    )

RCT_EXTERN_METHOD(fetchMobileKeys:
                    resolver:(RCTPromiseResolveBlock)resolve
                    rejecter:(RCTPromiseRejectBlock)reject
                )

- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

+ (BOOL)requiresMainQueueSetup
{
    return YES;
}

@end

// end of file

RNMyModule.swift

import BLESDK
import CoreBluetooth

@objc(RNMyModule)
class RNMyModule: NSObject, BLEManagerDelegate {
  // Promise resolvers for JS
    var _resolve: RCTPromiseResolveBlock?
    var _reject: RCTPromiseRejectBlock?

  // EXPOSED REACT NATIVE FUNCTIONS
    @objc func initializeBLESDK(_ UUID: String,
                        resolver resolve: @escaping RCTPromiseResolveBlock,
                        rejecter reject: @escaping RCTPromiseRejectBlock) -> Void {
        self._resolve = resolve;
        self._reject = reject;
        BLEManager.shared().initializeBLESDK(UUID, withDelegate: self);
    }

    @objc func fetchMobileKeys(_ Empty: String,
                        resolver resolve: @escaping RCTPromiseResolveBlock,
                        rejecter reject: @escaping RCTPromiseRejectBlock) -> Void {
        self._resolve = resolve;
        self._reject = reject;
        BLEManager.shared().fetchMobileKeys(self)
    }

    // DELEGATE CALLBACKS

    // this method is called after `BLEManager.shared().initializeBLESDK` completes
    // and it works just fine in my App.js file
    func initializeBLESDKResponse(_ response: String!, status endpointStatus: Bool) {
        if (endpointStatus) {
            self._resolve?(response)
            return
        }
        self._reject?(false)

    }


    // this method is called after `BLEManager.shared().fetchMobileKeys(self)` completes
    // HOWEVER: Because fetchMobileKeys scans for devices, this function gets called more than 
    // once by the delegate, each time it completes a scan. The second time this function is 
    // called, my react native applications throws the error:
    // Illegal callback invocation from native module. This callback type only permits a single 
    // invocation from native code.

    func fetchMobileKeysResponse(_ response: String!, status keysStatus: Bool) {
        if (!keysStatus) {
            return
        }
        self.resolve?(reponse);
    }

}

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

Есть ли способ перехватить обратный вызов делегата, чтобы я мог использовать RCTEventEmitter, как описано в этом посте здесь: https://medium.com/nycdev/calling-a-callback-multiple-times-in-a-react-native-module-5c3c61f2fca4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...