当前位置: 首页 > 知识库问答 >
问题:

React Native Module中的EADemo永远不会收到委托方法handleEvent NSStreamEventOpenComplated?

汪高岑
2023-03-14

我希望我有一个react本机网桥模块、线程、委托或生存期问题,我不理解这会阻止委托方法调用被接收。

我需要更改NSStream ScheduleInRunload方法吗?

我试图实现一个反应本机iOS桥模块,以连接基于Apple的EADemo示例的蓝牙“经典”(不是BLE)外部附件。EADemo独立运行良好。

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

我希望handleEvent接收inputStream和outputStream的NSStreamEventTopEncompleted事件。然而,没有收到任何事件。

文件:索引。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

非常感谢您的任何提示或建议。

共有1个答案

宗政功
2023-03-14

解决了。

将此添加到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();
}

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

现在是EADSessionController。EADemo示例中的m可以从react本机网桥模块中调用,没有问题。

 类似资料:
  • 问题内容: 在下一个代码中,我尝试调用deinit方法以释放对该实例的所有引用,但从未调用过deinit。为什么? 问题答案: 适用于Swift的Xcode 不能像常规应用程序一样工作;它们不只运行一次。创建的对象保留在内存中,可以检查直到更改代码为止,此时将重新评估整个操场。发生这种情况时,所有先前的结果都将被丢弃,并且所有对象都将被释放时,您将看不到任何结果。 您的代码是正确的,但是Playg

  • 在收到远程通知并且用户采取操作(而不是关闭/解除)之后,app委托获得回调: -(void)application:(UIApplication*)application DidReceiverEmoTentification:(NSDictionary*)userInfo FetchCompletionHandler:(void(^)(UIBackgroundFetchResult))compl

  • 我想在我的应用程序中使用插屏广告,所以我实现了所有必要的委托方法。问题是,如果我使用[self Request estInterstitialAdPresent]来显示广告,只有interstitialAdddLoad:方法被调用。interstitialAdActionddFinish:方法没有被调用... 但是,如果我使用已弃用的[self.interstitialPresinFromView

  • 本文向大家介绍C#中委托(Delegates)的使用方法详解,包括了C#中委托(Delegates)的使用方法详解的使用技巧和注意事项,需要的朋友参考一下 1. 委托是什么? 其实,我一直思考如何讲解委托,才能把委托说得更透彻。说实话,每个人都委托都有不同的见解,因为看问题的角度不同。个人认为,可以从以下2点来理解:  (1) 从数据结构来讲,委托是和类一样是一种用户自定义类型。  (2) 从设计

  • 本文向大家介绍C#中的委托是什么?事件是不是一种委托?事件和委托的关系。相关面试题,主要包含被问及C#中的委托是什么?事件是不是一种委托?事件和委托的关系。时的应答技巧和注意事项,需要的朋友参考一下 委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数的指针。 委托和事件没有可比性,因为委托是类型,事件是对象,下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实

  • 1.子类扩展父类。2.子类实现Cloneable并重写clone()方法调用super。clone()3.父类既不实现Cloneable接口,也不重写clone(()方法。 输出:克隆父类和子类状态。 问题:在父类没有实现标记接口Cloneable的情况下,父类状态如何被对象类克隆?