Я ожидаю, что у меня есть модуль React Native Bridge, многопоточность , делегат или проблема жизненного цикла, которую я не понимаю, которая препятствует получению вызовов метода делегата.
Нужно ли менять методы NSStream scheduleInRunLoop?
Я пытаюсь реализовать модуль моста iOS для реакции для подключения Bluetooth "Classic" (не BLE) Внешний аксессуар на основе Пример EADemo от Apple. EADemo прекрасно работает автономно.
Когда я вызываю EADSessionController openSession из собственного метода моста реакции, метод handleEvent никогда не вызывается?
Я ожидаю, что handleEvent получит событие NSStreamEventOpenCompleted как для inputStream, так и для outputStream. Однако получены нулевые события.
Файл: index.js
'use strict';
var RNBluetooth = require('react-native').NativeModules.RNBluetooth;
var Bluetooth = {
connectTo(accessory, result) {
RNBluetooth.connectTo(accessory, result);
},
};
module.exports = Bluetooth;
Файл: RNBluetooth.m
// open the external accesssory session from javascript
RCT_EXPORT_METHOD(connectTo:(NSDictionary *)accessoryProperties
callback:(RCTResponseSenderBlock)callback)
{
// findAccessory returns the EAAccessory matching the accessoryProperties
EAAccessory * accessory = [self findAccessory:accessoryProperties];
if(nil != accessory) {
NSLog(@"Connect to: {%@}", accessoryProperties[@"name"]);
NSLog(@"name: {%@}", accessory.name);
NSLog(@"serialNumber: {%@}", accessory.serialNumber);
NSLog(@"connectionID: {%d}", (int)accessory.connectionID);
}
// Singleton
EADSessionController * eaSessionController = [EADSessionController sharedController];
[eaSessionController setupControllerForAccessory:accessory
withProtocolString:accessoryProperties[@"protocolStrings"]];
[eaSessionController openSession];
NSString *dummyResponseString = @"openSession";
callback(@[dummyResponseString]);
}
Файл: EADSessionController.m
#import "EADSessionController.h"
NSString *EADSessionDataReceivedNotification = @"EADSessionDataReceivedNotification";
@implementation EADSessionController
@synthesize accessory = _accessory;
@synthesize protocolString = _protocolString;
#pragma mark Internal
#pragma mark Public Methods
+ (EADSessionController *)sharedController
{
static EADSessionController *sessionController = nil;
if (sessionController == nil) {
sessionController = [[EADSessionController alloc] init];
}
return sessionController;
}
- (void)dealloc
{
[self closeSession];
[self setupControllerForAccessory:nil withProtocolString:nil];
[super dealloc];
}
// initialize the accessory with the protocolString
- (void)setupControllerForAccessory:(EAAccessory *)accessory withProtocolString:(NSString *)protocolString
{
[_accessory release];
_accessory = [accessory retain];
[_protocolString release];
_protocolString = [protocolString copy];
}
// open a session with the accessory and set up the input and output stream on the default run loop
- (BOOL)openSession
{
[_accessory setDelegate:self];
_session = [[EASession alloc] initWithAccessory:_accessory forProtocol:_protocolString];
if (_session)
{
[[_session inputStream] setDelegate:self];
[[_session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[_session inputStream] open];
[[_session outputStream] setDelegate:self];
[[_session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[_session outputStream] open];
}
else
{
NSLog(@"creating session failed");
}
return (_session != nil);
}
// close the session with the accessory.
- (void)closeSession
{
[[_session inputStream] close];
[[_session inputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[_session inputStream] setDelegate:nil];
[[_session outputStream] close];
[[_session outputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[[_session outputStream] setDelegate:nil];
[_session release];
_session = nil;
[_writeData release];
_writeData = nil;
[_readData release];
_readData = nil;
}
#pragma mark EAAccessoryDelegate
- (void)accessoryDidDisconnect:(EAAccessory *)accessory
{
// do something ...
}
#pragma mark NSStreamDelegateEventExtensions
// handleEvent never gets called when session opened from react native bridge?
//
// asynchronous NSStream handleEvent method
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
case NSStreamEventNone:
break;
case NSStreamEventOpenCompleted:
break;
case NSStreamEventHasBytesAvailable:
[self _readData];
break;
case NSStreamEventHasSpaceAvailable:
[self _writeData];
break;
case NSStreamEventErrorOccurred:
break;
case NSStreamEventEndEncountered:
break;
default:
break;
}
}
@end
Любые советы или предложения очень ценятся.