diff --git a/android/src/main/java/com/gbike/segwayblemanager/SegwayBleManagerModule.kt b/android/src/main/java/com/gbike/segwayblemanager/SegwayBleManagerModule.kt index 74e2d44..41c87ba 100644 --- a/android/src/main/java/com/gbike/segwayblemanager/SegwayBleManagerModule.kt +++ b/android/src/main/java/com/gbike/segwayblemanager/SegwayBleManagerModule.kt @@ -2,6 +2,7 @@ package com.gbike.segwayblemanager import android.util.Log import com.facebook.react.bridge.Arguments +import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.WritableMap @@ -52,8 +53,8 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) * @see [ReactMethod.isBlockingSynchronousMethod] * @see [ReactMethod] */ - override fun getTypedExportedConstants(): MutableMap { - return mutableMapOf( + override val typedExportedConstants: MutableMap + = mutableMapOf( "supportedEvents" to listOf( "InitializeResult", "ConnectResult", @@ -67,7 +68,6 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) "IoTInfoResult", ), "moduleName" to NAME, ) - } /** * This method is sending device events to the JavaScript side. @@ -78,15 +78,18 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) deviceEventEmitter.emit(eventName, params) } - private fun onSuccess(eventName: String, result: Boolean) { + private fun onSuccess(eventName: String, result: Boolean, promise: Promise?) { val params = Arguments.createMap().apply { putBoolean("result", result) } Log.d(BLUETOOTH_KIT, "$eventName: $result") sendEvent(eventName, params) + if (promise !== null) { + promise.resolve(result) + } } - private fun onFailure(eventName: String, message: String, code: Int) { + private fun onFailure(eventName: String, message: String, code: Int, promise: Promise?) { val params = Arguments.createMap().apply { putBoolean("result", false) putString("message", message) @@ -94,9 +97,12 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) } Log.w(BLUETOOTH_KIT, "$eventName: $message") sendEvent(eventName, params) + if (promise !== null) { + promise.resolve(params) + } } - private fun onError(eventName: String, error: Exception) { + private fun onError(eventName: String, error: Exception, promise: Promise?) { val params = Arguments.createMap().apply { putBoolean("result", false) putString("errorMessage", error.localizedMessage) @@ -105,6 +111,9 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) } Log.e(BLUETOOTH_KIT, "$eventName: $error") sendEvent(eventName, params) + if (promise !== null) { + promise.reject(error) + } } @ReactMethod @@ -112,6 +121,7 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) secretKey: String?, operatorCode: String?, isDebug: Boolean, + promise: Promise? ) { val initializeResult = "InitializeResult" try { @@ -119,9 +129,9 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) bluetoothKit = BluetoothKit() bluetoothKit!!.init(reactContext) bluetoothKit!!.debugEnabled(isDebug) - onSuccess(initializeResult, true) + onSuccess(initializeResult, true, promise) } catch (error: Exception) { - onError(initializeResult, error) + onError(initializeResult, error, promise) } } @@ -130,62 +140,62 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) try { bluetoothKit!!.connect(deviceMac, deviceKey, iotImei) { state -> when (state) { - STATE_CONNECTED -> onSuccess(connectResult, true) - STATE_DISCONNECTED -> onFailure(connectResult, STRING_DISCONNECTED, -1001) - else -> onFailure(connectResult, STRING_CONN_FAILURE, -1004) + STATE_CONNECTED -> onSuccess(connectResult, true, null) + STATE_DISCONNECTED -> onFailure(connectResult, STRING_DISCONNECTED, -1001, null) + else -> onFailure(connectResult, STRING_CONN_FAILURE, -1004, null) } } } catch (error: Exception) { - onError(connectResult, error) + onError(connectResult, error, null) } } @ReactMethod - override fun disconnect() { + override fun disconnect(promise: Promise?) { val disconnectResult = "DisconnectResult" try { if (bluetoothKit != null) { bluetoothKit!!.disConnect() - onSuccess(disconnectResult, true) + onSuccess(disconnectResult, true, promise) } else { - onSuccess(disconnectResult, false) + onSuccess(disconnectResult, false, promise) } } catch (error: Exception) { - onError(disconnectResult, error) + onError(disconnectResult, error, promise) } } @ReactMethod - override fun unLock() { + override fun unLock(promise: Promise?) { val unlockResult = "UnlockResult" try { bluetoothKit!!.unLock(object : OnUnlockListener { override fun onUnlockSuccess() { - onSuccess(unlockResult, true) + onSuccess(unlockResult, true, promise) } override fun onUnlockFail(code: Int, msg: String) { - onFailure(unlockResult, msg, code) + onFailure(unlockResult, msg, code, promise) } }) } catch (error: Exception) { - onError(unlockResult, error) + onError(unlockResult, error, promise) } } @ReactMethod - override fun lock() { + override fun lock(promise: Promise?) { val lockResult = "LockResult" try { bluetoothKit!!.lock(object : OnLockListener { override fun onLockSuccess() { - onSuccess(lockResult, true) + onSuccess(lockResult, true, promise) } override fun onLockFail(code: Int, msg: String) { - onFailure(lockResult, msg, code) + onFailure(lockResult, msg, code, promise) } }) } catch (error: Exception) { - onError(lockResult, error) + onError(lockResult, error, promise) } } @@ -213,63 +223,63 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) sendEvent(eventName, params) } override fun onQueryVehicleInfoFail(code: Int, msg: String) { - onFailure(eventName, msg, code) + onFailure(eventName, msg, code, null) } }) } catch (error: Exception) { - onError(eventName, error) + onError(eventName, error, null) } } @ReactMethod - override fun openBatteryCover() { + override fun openBatteryCover(promise: Promise?) { val openCoverResult = "OpenCoverResult" try { bluetoothKit!!.openBatteryCover(object : OnOpenBatteryCoverListener { override fun OnOpenBatteryCoverSuccess() { - onSuccess(openCoverResult, true) + onSuccess(openCoverResult, true, promise) } override fun OnOpenBatteryCoverFail(code: Int, msg: String) { - onFailure(openCoverResult, msg, code) + onFailure(openCoverResult, msg, code, promise) } }) } catch (error: Exception) { - onError(openCoverResult, error) + onError(openCoverResult, error, promise) } } @ReactMethod - override fun openSaddle() { + override fun openSaddle(promise: Promise?) { val openSaddleResult = "OpenSaddleResult" try { bluetoothKit!!.openSaddle(object : OnOpenSaddleListener { override fun onOpenSaddleSuccess() { - onSuccess(openSaddleResult, true) + onSuccess(openSaddleResult, true, promise) } override fun onOpenSaddleFail(code: Int, msg: String) { - onFailure(openSaddleResult, msg, code) + onFailure(openSaddleResult, msg, code, promise) } }) } catch (error: Exception) { - onError(openSaddleResult, error) + onError(openSaddleResult, error, promise) } } @ReactMethod - override fun openTailBox() { + override fun openTailBox(promise: Promise?) { val openTailBoxResult = "OpenTailBoxResult" try { bluetoothKit!!.openTailBox(object : OnOpenTailBoxListener { override fun onOpenTailBoxSuccess() { - onSuccess(openTailBoxResult, true) + onSuccess(openTailBoxResult, true, promise) } override fun onOpenTailBoxFail(code: Int, msg: String) { - onFailure(openTailBoxResult, msg, code) + onFailure(openTailBoxResult, msg, code, promise) } }) } catch (error: Exception) { - onError(openTailBoxResult, error) + onError(openTailBoxResult, error, promise) } } @@ -297,7 +307,7 @@ class SegwayBleManagerModule(private val reactContext: ReactApplicationContext) sendEvent(eventName, params) } override fun onQueryIoTInfoFail(code: Int, msg: String) { - onFailure(eventName, msg, code) + onFailure(eventName, msg, code, null) } }) } diff --git a/android/src/oldarch/SegwayBleManagerSpec.kt b/android/src/oldarch/SegwayBleManagerSpec.kt index 03fde16..8e1e594 100644 --- a/android/src/oldarch/SegwayBleManagerSpec.kt +++ b/android/src/oldarch/SegwayBleManagerSpec.kt @@ -12,36 +12,33 @@ import java.util.* abstract class SegwayBleManagerSpec internal constructor(context: ReactApplicationContext) : ReactContextBaseJavaModule(context) { - protected abstract fun getTypedExportedConstants(): Map + protected abstract val typedExportedConstants: Map @DoNotStrip - fun getConstants(): Map? { - val constants = getTypedExportedConstants() + override fun getConstants(): Map? { + val constants = typedExportedConstants if (ReactBuildConfig.DEBUG || ReactBuildConfig.IS_INTERNAL_BUILD) { - val obligatoryFlowConstants: MutableSet = HashSet( - Arrays.asList( + val obligatoryFlowConstants: MutableSet = HashSet( + Arrays.asList( + "moduleName", "supportedEvents" ) ) - val optionalFlowConstants: Set = HashSet() - var undeclaredConstants: MutableSet = HashSet(constants.keys) + val optionalFlowConstants: Set = HashSet() + var undeclaredConstants: MutableSet = HashSet(constants.keys) undeclaredConstants.removeAll(obligatoryFlowConstants) undeclaredConstants.removeAll(optionalFlowConstants) - if (!undeclaredConstants.isEmpty()) { - throw IllegalStateException( - String.format( - "Native Module Flow doesn't declare constants: %s", - undeclaredConstants - ) + check(undeclaredConstants.isEmpty()) { + String.format( + "Native Module Flow doesn't declare constants: %s", + undeclaredConstants ) } undeclaredConstants = obligatoryFlowConstants undeclaredConstants.removeAll(constants.keys) - if (!undeclaredConstants.isEmpty()) { - throw IllegalStateException( - String.format( - "Native Module doesn't fill in constants: %s", - undeclaredConstants - ) + check(undeclaredConstants.isEmpty()) { + String.format( + "Native Module doesn't fill in constants: %s", + undeclaredConstants ) } } @@ -49,28 +46,33 @@ abstract class SegwayBleManagerSpec internal constructor(context: ReactApplicati } @ReactMethod @DoNotStrip - abstract fun init(secretKey: String?, operatorCode: String?, isDebug: Boolean) - @ReactMethod(isBlockingSynchronousMethod = true) + abstract fun init( + secretKey: String?, + operatorCode: String?, + isDebug: Boolean, + promise: Promise? + ) + @ReactMethod @DoNotStrip - abstract fun connect(deviceMac: String?, deviceKey: String?, iotImei: String?): Boolean - @ReactMethod(isBlockingSynchronousMethod = true) + abstract fun connect(deviceMac: String?, deviceKey: String?, iotImei: String?) + @ReactMethod @DoNotStrip - abstract fun disconnect(): Boolean - @ReactMethod(isBlockingSynchronousMethod = true) + abstract fun disconnect(promise: Promise?) + @ReactMethod @DoNotStrip - abstract fun unLock(): Boolean - @ReactMethod(isBlockingSynchronousMethod = true) + abstract fun unLock(promise: Promise?) + @ReactMethod @DoNotStrip - abstract fun lock(): Boolean - @ReactMethod(isBlockingSynchronousMethod = true) + abstract fun lock(promise: Promise?) + @ReactMethod @DoNotStrip - abstract fun openBatteryCover(): Boolean - @ReactMethod(isBlockingSynchronousMethod = true) + abstract fun openBatteryCover(promise: Promise?) + @ReactMethod @DoNotStrip - abstract fun openSaddle(): Boolean - @ReactMethod(isBlockingSynchronousMethod = true) + abstract fun openSaddle(promise: Promise?) + @ReactMethod @DoNotStrip - abstract fun openTailBox(): Boolean + abstract fun openTailBox(promise: Promise?) @ReactMethod @DoNotStrip abstract fun queryVehicleInformation() diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 4768e61..fc279d7 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -416,7 +416,7 @@ PODS: - React-perflogger (= 0.71.4) - RNPermissions (3.8.0): - React-Core - - SegwayBleManager (0.1.0): + - SegwayBleManager (0.1.2): - NBIoTBleKit (~> 1.1.1) - React-Core - SocketRocket (0.6.0) @@ -629,7 +629,7 @@ SPEC CHECKSUMS: React-runtimeexecutor: 8fa50b38df6b992c76537993a2b0553d3b088004 ReactCommon: b49a4b00ca6d181ff74b17c12b2d59ac4add0bde RNPermissions: afeeeab5f8614fc0eb0dd091537e1c19d2c0476c - SegwayBleManager: dcdacbb9367c9e4d26a3f5753643b1857ee58846 + SegwayBleManager: 513c3f5c3ff20e3e6449b06985fb841b3e348916 SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: 79dd7410de6f8ad73a77c868d3d368843f0c93e0 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a diff --git a/ios/SegwayBleManager.h b/ios/SegwayBleManager.h index ec06790..50db9e9 100644 --- a/ios/SegwayBleManager.h +++ b/ios/SegwayBleManager.h @@ -17,16 +17,24 @@ - (void)init:(NSString *)secretKey operatorCode:(NSString *)operatorCode - isDebug:(BOOL)isDebug; + isDebug:(BOOL)isDebug + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; - (void)connect:(NSString *)deviceMac deviceKey:(NSString *)deviceKey iotImei:(NSString *)iotImei; -- (void)disconnect; -- (void)unLock; -- (void)lock; -- (void)openBatteryCover; -- (void)openSaddle; -- (void)openTailBox; +- (void)disconnect:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)unLock:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)lock:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)openBatteryCover:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)openSaddle:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)openTailBox:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; - (void)queryVehicleInformation; - (void)queryIoTInformation; - (void)addListener:(NSString *)eventType; diff --git a/ios/SegwayBleManager.mm b/ios/SegwayBleManager.mm index c272f2b..ed1c966 100644 --- a/ios/SegwayBleManager.mm +++ b/ios/SegwayBleManager.mm @@ -1,7 +1,28 @@ #import "SegwayBleManager.h" #import -@implementation SegwayBleManager +@interface SegwayBleManager() + +@property(nonatomic, copy) RCTPromiseResolveBlock unlockResolve; +@property(nonatomic, copy) RCTPromiseRejectBlock unlockReject; + +@property(nonatomic, copy) RCTPromiseResolveBlock lockResolve; +@property(nonatomic, copy) RCTPromiseRejectBlock lockReject; + +@property(nonatomic, copy) RCTPromiseResolveBlock batteryCoverResolve; +@property(nonatomic, copy) RCTPromiseRejectBlock batteryCoverReject; + +@property(nonatomic, copy) RCTPromiseResolveBlock saddleResolve; +@property(nonatomic, copy) RCTPromiseRejectBlock saddleReject; + +@property(nonatomic, copy) RCTPromiseResolveBlock tailBoxResolve; +@property(nonatomic, copy) RCTPromiseRejectBlock tailBoxReject; + +@end + +@implementation SegwayBleManager { + bool hasListeners; +} RCT_EXPORT_MODULE(); @@ -24,6 +45,14 @@ + (BOOL)requiresMainQueueSetup { ]; } +- (void)startObserving { + hasListeners = YES; +} + +- (void)stopObserving { + hasListeners = NO; +} + - (void)onSuccess:(NSString *)eventName result:(BOOL)result { NSString * toBool = result ? @"true" : @"false"; @@ -50,23 +79,26 @@ - (void)onFailure:(NSString *)eventName /// @param completionHandler called when the register is finished. RCT_EXPORT_METHOD(init:(NSString *)secretKey operatorCode:(NSString *)operatorCode - isDebug:(BOOL)isDebug) { + isDebug:(BOOL)isDebug + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) { if (isDebug) { [NBIoTBleService.shared setIsDebugEnabled:isDebug]; } [NBIoTBleService.shared startWithOperatorCode:operatorCode andSecret:secretKey + /// cSpell:ignoreWord: Hanlder completionHanlder:^(BOOL isSuccess, NSError * _Nullable error) { - if (error) { + if (error) { NSLog(@"%@", error); - [self onFailure:@"InitializeResult" - message:error.description - code:error.code]; - } else { - [self onSuccess:@"InitializeResult" - result:isSuccess]; - } - }]; + [self onFailure:@"InitializeResult" + message:error.description + code:error.code]; + } else { + [self onSuccess:@"InitializeResult" + result:isSuccess]; + } + }]; }; RCT_EXPORT_METHOD(queryVehicleInformation) { @@ -77,6 +109,10 @@ - (void)onFailure:(NSString *)eventName [self.iotController queryIoTInformation]; }; +/// try to connect bluetooth equipment +/// @param iotImei imei +/// @param deviceMac mac address +/// @param deviceKey device key RCT_EXPORT_METHOD(connect:(NSString *)deviceMac deviceKey:(NSString *)deviceKey iotImei:(NSString *)iotImei) { @@ -86,27 +122,43 @@ - (void)onFailure:(NSString *)eventName andDeviceKey:deviceKey]; }; -RCT_EXPORT_METHOD(disconnect) { +RCT_EXPORT_METHOD(disconnect:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) { [self.iotController disconnect]; } -RCT_EXPORT_METHOD(unLock) { +RCT_EXPORT_METHOD(unLock:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) { + self.unlockResolve = resolve; + self.unlockReject = reject; [self.iotController unlock]; }; -RCT_EXPORT_METHOD(lock) { +RCT_EXPORT_METHOD(lock:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) { + self.lockResolve = resolve; + self.lockReject = reject; [self.iotController lock]; }; -RCT_EXPORT_METHOD(openBatteryCover){ +RCT_EXPORT_METHOD(openBatteryCover:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject){ + self.batteryCoverResolve = resolve; + self.batteryCoverReject = reject; [self.iotController openBatteryCover]; }; -RCT_EXPORT_METHOD(openSaddle){ +RCT_EXPORT_METHOD(openSaddle:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject){ + self.saddleResolve = resolve; + self.saddleReject = reject; [self.iotController openSaddle]; }; -RCT_EXPORT_METHOD(openTailBox){ +RCT_EXPORT_METHOD(openTailBox:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject){ + self.tailBoxResolve = resolve; + self.tailBoxReject = reject; [self.iotController openTailBox]; };