iOS9上的NSInputStream永远不会有HasBytesAvailable(经典蓝牙)

时间:2015-09-24 04:42:31

标签: ios8 bluetooth xamarin xamarin.ios ios9

我有一个跨平台(Xamrin)应用程序,可以进行一些经典的蓝牙通信,并且在iOS8上工作得非常好。但是,在iOS9上重新构建并运行它后,我无法让NSInputStream拥有" HasBytesAvailable" = true。注意:I followed all the instructions from Xamarin's website.

我尝试将委托分配给InputStream并等待NSRunLoop但是流似乎永远不会有字节可用。该事件仅在打开输入流时触发(在iOS9上)(在iOS8上按预期触发)。

以下是在iOS8上成功读取的代码片段(委托方法):

EAsession.InputStream.Delegate = new Foo();    
EAsession.InputStream.Schedule(NSRunLoop.Current,NSRunLoop.NSDefaultRunLoopMode);
    EAsession.InputStream.Open();           
    (NSRunLoop.Current).RunUntil(NSDate.FromTimeIntervalSinceNow(2));

Foo 是一个实现的类:NSObject,INSStreamDelegate

    public class Foo :NSObject, INSStreamDelegate
{
    [Export("stream:handleEvent:")]
    public void HandleEvent(Foundation.NSStream theStream, Foundation.NSStreamEvent streamEvent)
    {
      //Code to read bytes here
    }

为了确保确实有发送到iPhone5的字节,我修改了外部蓝牙设备,只是回显收到的任何字节。

在iOS8上使用任一方法(委托或等待NSRunLoop),回声立即到达。但是,当我将目标设备更改为iOS9时,我可以永远等待,并且HasBytesAvailable将始终为false。

我甚至尝试阅读,不管HasBytesAvailable是否为假,但没有任何内容正在阅读中(我猜没有什么大惊喜)。

此外,我尝试使用Xcode6.4和Xcode 7构建相同的结果。

目前我没有想法,所以任何帮助都会非常感激!

提前致谢!

修改

我联系了Xamarin,我正在为他们编写一个测试应用程序,以测试它是Apple问题还是Xamarin问题。

另外,请参阅this link中有关蓝牙的评论......也许相关?

2 个答案:

答案 0 :(得分:1)

我能够通过打开一个我无意使用的EAAccessory的InputStream来解决这个问题。我的猜测是输入和输出流都是新iOS9蓝牙合约的一部分。这是我工作代码的相关更新:

            accessory.Delegate = new EAAccessoryDelegateHandler ();

            if (PrinterSession == null)
            {
                PrinterSession = new EASession (accessory, PrintProtocol);

            }
            var mysession = PrinterSession;

            mysession.InputStream.Open();

            mysession.OutputStream.Delegate = this;
            mysession.OutputStream.Schedule (NSRunLoop.Current, NSRunLoop.NSDefaultRunLoopMode);
            mysession.OutputStream.Open ();

然后当我关闭OutputStream时,我会立即关闭未使用的InputStream。

答案 1 :(得分:1)

所以我终于解决了,

我不能完全确定最终会出现什么问题,因为我做了一些事情:

  1. 更新到Xamarin beta流(5.9.7版本12)。
  2. 更新到最新的iOS(9.0.2)
  3. 使用Xcode 7.0
  4. 改变我给代表打电话的地方,打开流程和日程安排。
  5. 对代码的更改是,我不是单独处理接收和发送方法中的开放,调度和委托分配,而是在同一个地方完成。也就是说,在创建EASession时,我分配了以上所有内容:

            s = new EASession(device, protocol);
            output_stream = s.OutputStream;
            input_stream = s.InputStream;
    
            output_stream.Delegate=this;
            output_stream.Schedule(NSRunLoop.Current, NSRunLoop.NSDefaultRunLoopMode);
            output_stream.Open();
    
            input_stream.Delegate = this;
            input_stream.Schedule(NSRunLoop.Current, NSRunLoop.NSDefaultRunLoopMode);
            input_stream.Open();
    

    目前我没有安排输入和输出流,我不确定这是正确的做法。我将尝试保持更新,因为我从工作转移到一个看起来很好看的代码......

    与Bluecode描述的不同,我肯定需要使用我的输入流,而且我总是打开它;所以我不确定这是不是同一个问题。我仍然不确定该问题的解决方案是什么,因为它可以是上述中的一个或组合。稍后当我有更多时间看看哪一个是单一解决方案时,我可能会对此进行更多的实验?如果有的话。

    希望这对任何人都有帮助。 干杯