Отрешите проблемы выбросов событий нативного модуля с iOSJavascript

Форум по Javascript
Ответить
Anonymous
 Отрешите проблемы выбросов событий нативного модуля с iOS

Сообщение Anonymous »

setup
У меня есть нативный модуль, который расширяет rcteventemitter, а также реализует турбомодуль Спецификация:
shrong>rctnativeLocalStorage.h:>
#import
#import

NS_ASSUME_NONNULL_BEGIN
@interface RCTNativeLocalStorage : RCTEventEmitter
@end
NS_ASSUME_NONNULL_END

rctnativelocalstorage.m (частично):

Код: Выделить всё

#import "RCTNativeLocalStorage.h"
#import 
#import 

using namespace facebook;

@interface RCTNativeLocalStorage () 
@property (strong, nonatomic) NSUserDefaults *localStorage;
@property (strong, nonatomic) CBCentralManager *centralManager;
@property (strong, nonatomic) NSMutableArray *discoveredDevices;
@property (nonatomic, assign) BOOL hasListeners;
@end

@implementation RCTNativeLocalStorage

// Register the module
RCT_EXPORT_MODULE(NativeLocalStorage)

// These methods are required for NativeEventEmitter to work properly
RCT_EXPORT_METHOD(addListener:(NSString *)eventName)
{
NSLog(@"🎧 addListener called for: %@", eventName);
}

RCT_EXPORT_METHOD(removeListeners:(double)count)
{
NSLog(@"🔕 removeListeners called: %f", count);
}

// Define supported events
- (NSArray *)supportedEvents {
return @[
@"BluetoothDeviceFound",
];
}

// Event listener tracking
- (void)startObserving {
NSLog(@"✅ startObserving called - events will be emitted");
self.hasListeners = YES;
}

- (void)stopObserving {
NSLog(@"⚠️ stopObserving called - events will not be emitted");
self.hasListeners = NO;
}

- (instancetype)init {
if (self = [super init]) {
_localStorage = [[NSUserDefaults alloc] initWithSuiteName:@"local-storage"];
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
_discoveredDevices = [NSMutableArray new];
_hasListeners = NO;
}
return self;
}

+ (BOOL)requiresMainQueueSetup {
return NO;
}

// TurboModule implementation
- (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
return std::make_shared(params);
}

// MARK: - TurboModule Methods

- (NSString * _Nullable)getItem:(NSString *)key {
return [self.localStorage stringForKey:key];
}

- (void)setItem:(NSString *)value key:(NSString *)key {
[self.localStorage setObject:value forKey:key];
}

- (void)removeItem:(NSString *)key {
[self.localStorage removeObjectForKey:key];
}

- (void)clear {
NSDictionary *allItems = [self.localStorage dictionaryRepresentation];
for (NSString *key in allItems.allKeys) {
[self.localStorage removeObjectForKey:key];
}
}

// Export the startScan method to make it available to JavaScript
RCT_EXPORT_METHOD(startScan) {
NSLog(@"✅ startScan triggered from JavaScript");

if (_centralManager.state != CBManagerStatePoweredOn) {
NSLog(@"❌ Bluetooth not powered on");
return;
}

// Show an alert to verify the method was called
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Scan"
message:@"startScan called!"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK"  style:UIAlertActionStyleDefault handler:nil];
[alert addAction:ok];
UIViewController *root = UIApplication.sharedApplication.keyWindow.rootViewController;
[root presentViewController:alert animated:YES completion:nil];
});

[_discoveredDevices removeAllObjects];
[_centralManager scanForPeripheralsWithServices:nil options:nil];
}

// Central Manager Delegates
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
switch (central.state) {
case CBManagerStatePoweredOn:
NSLog(@"✅ Bluetooth is powered on.");
break;
case CBManagerStatePoweredOff:
NSLog(@"❌ Bluetooth is powered off.");
break;
default:
NSLog(@"⚠️ Bluetooth state changed: %ld", (long)central.state);
break;
}
}

- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {

NSString *deviceName = peripheral.name ?: @"Unknown";
NSString *deviceId = peripheral.identifier.UUIDString;

NSDictionary *deviceInfo = @{
@"name": deviceName,
@"id": deviceId
};

BOOL alreadyExists = NO;
for (NSDictionary *existingDevice in _discoveredDevices) {
if ([existingDevice[@"id"] isEqualToString:deviceId]) {
alreadyExists = YES;
break;
}
}

if (!alreadyExists) {
[_discoveredDevices addObject:deviceInfo];
NSLog(@"✅ Device discovered: %@", deviceInfo);

// Send event directly on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
// The hasListeners check is important to avoid the warning
if (self.hasListeners) {
NSLog(@"🚀 Sending BluetoothDeviceFound event");
[self sendEventWithName:@"BluetoothDeviceFound" body:deviceInfo];
} else {
NSLog(@"⚠️ No listeners registered for BluetoothDeviceFound event");
}
});
}
}

@end
код Javascript:

const { NativeLocalStorage } = NativeModules;
const eventEmitter = new NativeEventEmitter(NativeLocalStorage);

useEffect(() => {
console.log('Setting up event listener...');

const subscription = eventEmitter.addListener(
'BluetoothDeviceFound',
(deviceInfo) => {
console.log('Device found:', deviceInfo);
// Update state...
}
);

console.log('Starting scan...');
NativeLocalStorage.startScan();

return () => subscription.remove();
}, []);
< /code>
Консоль✅ Bluetooth is powered on.
'`new NativeEventEmitter()` was called with a non-null argument without the required `addListener` method.', { [Component Stack] name: 'Component Stack' }
'`new NativeEventEmitter()` was called with a non-null argument without the required `removeListeners` method.', { [Component Stack] name: 'Component Stack' }
✅ startScan triggered from JavaScript
✅ Device discovered: {
id = "E2DEF552-4C7E-FA6F-1CC3-3F6B0DE3CC31";
name = Unknown;
}
⚠️ No listeners registered for BluetoothDeviceFound event
⚠️ No listeners registered for BluetoothDeviceFound event
⚠️ No listeners registered for BluetoothDeviceFound event
< /code>
Проблема < /strong> < /p>
Невозможно отправить события из нативного кода iOS.
Тот же код работает с Android, и я могу отправлять данные слушателям событий. https://reactnative.dev/docs/0.77/legac ... javascript


Подробнее здесь: https://stackoverflow.com/questions/795 ... s-with-ios
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»