React Native Module中的EADemo从未收到委托方法handleEvent NSStreamEventOpenCompleted吗?

山的爱德

我期望我有一个我不明白反应本机桥模块,线程,委托或生命周期问题,这阻止了接收委托方法调用。

我是否需要更改NSStream scheduleInRunLoop方法?

我试图基于Apple的EADemo示例,实现一个react native iOS桥接模块来连接蓝牙“ Classic”(不是BLE)外部附件EADemo可独立运行。

当我从react本机网桥方法调用EADSessionController openSession时,从未调用handleEvent方法吗?

我希望handleEvent可以inputStreamoutputStream接收一个NSStreamEventOpenCompleted事件但是,接收到零事件。

档案: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

任何提示或建议,不胜感激。

山的爱德

解决了。

将此添加到RNBluetooth.m

// This seems to get NSStream handleEvents and the write command
// running on the same thread with no contention problems 
// writing to and reading from the write buffer
- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

请参阅本机模块下的线程部分

现在,可以从react本机网桥模块调用EADemo示例中EADSessionController.m而不会出现任何问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章