xamarin ios 应用程序因 CBCentralManager 崩溃

use*_*362 1 xamarin.ios

我有一个新的应用程序,除了以下代码之外,基本上没有添加任何代码。如果我在模拟器中尝试它,它会进入更新状态并显示不受支持。如果我尝试在第 6 代 ipad(打开蓝牙)上运行,一旦调试退出 UIButton231_TouchUpInside,应用程序就会崩溃(并且永远不会进入捕获状态)。

我错过了什么吗?

        CBCentralManager _central;
    partial void UIButton231_TouchUpInside(UIButton sender)
    {
        try
        {
            BluetoothLEManager();
        }
        catch (Exception e)
        {
            Console.Write(e);
        }
    }

    protected void BluetoothLEManager()
    {
        try
        {
            _central = new CBCentralManager(DispatchQueue.CurrentQueue);
            _central.DiscoveredPeripheral += (object sender, CBDiscoveredPeripheralEventArgs e) =>
            {
                Console.WriteLine("DiscoveredPeripheral: " + e.Peripheral.Name);
                Console.WriteLine("RSSI: " + e.Peripheral.RSSI);
            };

            _central.UpdatedState += (object sender, EventArgs e) =>
            {
                Console.WriteLine("UpdatedState: " + _central.State);
            };


            _central.ConnectedPeripheral += (object sender, CBPeripheralEventArgs e) =>
            {
                Console.WriteLine("ConnectedPeripheral: " + e.Peripheral.Name);

            };

            _central.DisconnectedPeripheral += (object sender, CBPeripheralErrorEventArgs e) =>
            {
                Console.WriteLine("DisconnectedPeripheral: " + e.Peripheral.Name);
            };
        }
        catch (Exception e)
        {
            Console.Write(e);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在下图中(代码被压缩以使图像更短),调试到达第 62 行就很好,但尝试单步跳过或只是让它继续将关闭应用程序,并且不会到达 catch 中的断点。

在此输入图像描述

Jun*_*ang 6

我已经尝试在本地站点中共享代码,它也崩溃并出现一些错误日志:

崩溃日志

检查此行错误后:

执行本机代码时收到 SIGABRT。这通常表示单声道运行时或应用程序使用的本机库之一中存在致命错误。

有时这可能是由 iOS 中的权限引起的。你可以看看James的这篇文章:新的iOS 10隐私权限设置

从iOS 10开始,几乎所有需要请求授权的API以及其他API,例如打开相机或照片库,都需要一个新的键值对来描述它们在Info.plist中的用法。

但是,在中info.plist,您可以轻松地添加蓝牙的权限,如下所示,并且会忘记另一个最重要的权限:

<key>NSBluetoothPeripheralUsageDescription</key>
<string>Add BlueTooth Peripheral Permission</string>
Run Code Online (Sandbox Code Playgroud)

这对于蓝牙来说还不够。您还需要添加另一个权限:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>use Bluetooth</string>
Run Code Online (Sandbox Code Playgroud)

从原生info.plist,你也会找到它。

在此输入图像描述

该许可是基本且必要的。因为这会在iOS设备中弹出一个权限对话框窗口。

在此输入图像描述

顺便说一下,Xamarin iOS 中有一个关于使用蓝牙的官方 API,你可以看一下。

public class MySimpleCBCentralManagerDelegate : CBCentralManagerDelegate
{
        override public void UpdatedState (CBCentralManager mgr)
        {
            if (mgr.State == CBCentralManagerState.PoweredOn) {
                //Passing in null scans for all peripherals. Peripherals can be targeted by using CBUIIDs
                CBUUID[] cbuuids = null;
                mgr.ScanForPeripherals (cbuuids); //Initiates async calls of DiscoveredPeripheral
                //Timeout after 30 seconds
                var timer = new Timer (30 * 1000);
                timer.Elapsed += (sender, e) => mgr.StopScan();
            } else {
                //Invalid state -- Bluetooth powered down, unavailable, etc.
                System.Console.WriteLine ("Bluetooth is not available");
            }
        }
    public override void DiscoveredPeripheral (CBCentralManager central, CBPeripheral peripheral, NSDictionary advertisementData, NSNumber RSSI)
    {
        Console.WriteLine ("Discovered {0}, data {1}, RSSI {2}", peripheral.Name, advertisementData, RSSI);
    }

}
public partial class HelloBluetoothCSharpViewController : UIViewController
{
MySimpleCBCentralManagerDelegate myDel;
    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

  //Important to retain reference, else will be GC'ed
        myDel = new MySimpleCBCentralManagerDelegate ();
        var myMgr = new CBCentralManager (myDel, DispatchQueue.CurrentQueue);

    }
Run Code Online (Sandbox Code Playgroud)