xamarin ios 应用程序因 CBCentralManager 崩溃

Posted

技术标签:

【中文标题】xamarin ios 应用程序因 CBCentralManager 崩溃【英文标题】:xamarin ios app crashing with CBCentralManager 【发布时间】:2020-02-03 19:08:12 【问题描述】:

我有一个 Fresh 应用程序,除了以下代码之外,基本上没有添加任何代码。 如果我在模拟器中尝试它会进入更新状态并说不受支持。 如果我尝试在第 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);
        
    

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

【问题讨论】:

嗨,你能得到崩溃日志或者你可以分享 creah 截图。 没有崩溃画面。在 ipad 上,应用程序刚刚关闭。我在上面编辑了我的帖子以在调试时显示故障点....我无法在 entitlement.plist 中找到有关蓝牙的任何内容.... xamarin.ios 上是否有与“uses-feature”中的“uses-feature”等效的内容安卓清单? 您的意思是 Xamarin.iOS 中 info.plist 的 iOS Security and Privacy Features 吗? 这就是我的意思,但我尝试添加 UIRequiredDeviceCapabilitiespeer-peerbluetooth-lelocation-services 没有运气。行为还是一样的...... 好的,我会在本地站点检查它。如果解决方案将在这里分享。 【参考方案1】:

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

检查此行错误后:

在执行本机代码时获得了 SIGABRT。这通常表示 mono 运行时或您的应用程序使用的本机库之一中存在致命错误。

有时这可能是由 iOS 中的权限引起的。你可以看看 James 的这篇文章:New iOS 10 Privacy Permission Settings

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

然而,在info.plist,你可以很容易地添加蓝牙的权限,如下所示,会忘记另一个最重要的权限:

<key>NSBluetoothPeripheralUsageDescription</key>
<string>Add BlueTooth Peripheral Permission</string>

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

<key>NSBluetoothAlwaysUsageDescription</key>
<string>use Bluetooth</string>

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

此权限是基本且必要的。因为这会在iOS设备中弹出一个权限Dialog窗口。

顺便说一下,有an offical API关于在Xamarin iOS中使用蓝牙你可以看看。

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);

    

【讨论】:

感激不尽!非常感谢您与我的努力。 Junior Jiang - 我实现了上面相同的代码,并发现了最近的可用设备,但 peripheral.name 及其 UUID 始终为空。我只能获得“.data and RSSI”而不是 UUID 及其名称,为什么?你能帮忙吗 @Prasanth 你好,先检查一下蓝牙设备是否设置了名称。然后用另一部手机测试是否有效。 @JuniorJiang-MSFT 我试过它不起作用,我还有一个疑问 - 使用上面的代码它只显示 Apple/iOS 设备,但我也想要非 Apple 产品。与默认相同 - iOS 蓝牙搜索。我知道它应该只与完全相同的协议设备通信。您能否建议哪个蓝牙加密狗能够从 iOS 代码(产品/制造商名称)中检测到。实际上,我想通过外部蓝牙加密狗从 iOS 设备与 Windows PC 进行通信。任何想法请帮助我。抱歉,消息迟到了 @Prasanth Okey,很抱歉不熟悉这个场景。一般来说,iOS设备可以检测到所有的蓝牙设备,无论是非苹果产品,如蓝牙手表、耳机等。我认为他们没有限制通过蓝牙连接到苹果设备。我觉得唯一能做的就是保证蓝牙外设的信号比较稳定,信号强度也比较强。这样更有利于以后的工作。

以上是关于xamarin ios 应用程序因 CBCentralManager 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin Android 应用程序因“意图必须包含显式包名称来构建 android-app”而崩溃

Xamarin.mac 资源本地化不会因当前文化而改变

Xamarin.forms(或)xamarin.ios/xamarin.android(或)本机

有哪些ios或android应用是用xamarin开发的

Xamarin.Forms 无法更改本地设备上 Xamarin.iOS 中的应用程序图标

Xamarin.IOS 和 Signalr 推送通知