为啥我无法在 SwiftUI 中检测到使用 CoreBluetooh 的其他蓝牙设备?

Posted

技术标签:

【中文标题】为啥我无法在 SwiftUI 中检测到使用 CoreBluetooh 的其他蓝牙设备?【英文标题】:Why I couldn't detect other Bluetooth devices using CoreBluetooh in SwiftUI?为什么我无法在 SwiftUI 中检测到使用 CoreBluetooh 的其他蓝牙设备? 【发布时间】:2021-08-16 13:55:08 【问题描述】:

我创建了一个简单的应用程序,试图对我的 iPhone 周围的蓝牙设备进行 detech。我遵循了这个教程:BLE Development for ios

这是我的代码:

观点:

struct BluetoothDevicesView: View 
@ObservedObject var bleManager = BLEManager()

var body: some View 
    VStack (spacing: 10) 
        Text("Bluetooth Devices")
            .font(.largeTitle)
            .frame(maxWidth: .infinity, alignment: .center)
        
        List(bleManager.peripherals)  peripheral in
            HStack 
                Text(peripheral.name)
                Spacer()
                Text(String(peripheral.rssi))
            
        
        .frame(height: UIScreen.main.bounds.height/2)
        
        Spacer()
        
        Text("STATUS")
            .font(.headline)
        
        // Status goes here
        if bleManager.isSwitchedOn 
            Text("Bluetooth is switched on")
                .foregroundColor(.green)
        
        else 
            Text("Bluetooth is NOT switched on")
                .foregroundColor(.red)
        
        
        Spacer()
        VStack (spacing: 25) 
            Button(action: 
                bleManager.startScanning()
            ) 
                Text("Start Scanning")
            
            Button(action: 
                bleManager.stopScanning()
            ) 
                Text("Stop Scanning")
            
        .padding()
        Spacer()
    


接下来是BLEManager.swift

import Foundation
import CoreBluetooth

struct Peripheral: Identifiable 
let id: Int
let name: String
let rssi: Int


class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate 

var myCentral: CBCentralManager!
@Published var isSwitchedOn = false
@Published var peripherals = [Peripheral]()

override init() 
    super.init()
    
    myCentral = CBCentralManager(delegate: self, queue: nil)
    myCentral.delegate = self


func centralManagerDidUpdateState(_ central: CBCentralManager) 
    if central.state == .poweredOn 
        isSwitchedOn = true
    
    else 
        isSwitchedOn = false
    


func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) 
    let newPeripheral = Peripheral(id: peripherals.count, name: peripheral.name ?? "Unknown", rssi: RSSI.intValue)
    print(newPeripheral)
    peripherals.append(newPeripheral)
print("peripheral: \(peripheral)")



func startScanning() 
    print("startScanning")
    myCentral.scanForPeripherals(withServices: nil, options: nil)


func stopScanning() 
    print("stopScanning")
    myCentral.stopScan()

didDiscover peripheral 中,我将源代码更改为当前代码,因为它的结果相同。现在,当我运行它时,它会显示如下内容:

我的设备周围有 iPad、Mac、K1 设备(某种 android),但它们在哪里?在蓝牙设置中可以检测到它们,但通过这个应用程序我不能。

谁能解释为什么我无法检测到它们?在检测到的 10 个蓝牙中,为什么只检测到其中的 2 个?为什么在我的情况下其他人检测为nulUnknown?我错过了什么吗?

任何帮助将不胜感激,谢谢

更新:

我打印print("peripheral: \(peripheral)"),结果是这样的。这么多(`null'),我希望它们是名字。

【问题讨论】:

您正在检测这些设备,只是不知道它们的名字。广告并不总是包含设备名称。如果您实际连接到设备,您通常会看到设备名称。 Paulw 是正确的。尝试为每个外围设备打印广告数据——其中可能包含名称或其他有用信息。 您好,谢谢您的回答。打印advertisementData 会给我一堆我无法阅读或向您解释的单词和数字,但打印peripheral 并不总是给我设备名称。虽然设置上的蓝牙可以检测到他们的名字,甚至是我想要检测的安卓设备或笔记本电脑。为什么我检测不到他们的名字?它总是(null)。我不想连接它们,现在只检测它们。有什么建议吗?请检查屏幕截图更新。 @Paulw11 @Adam 另外,如果我想问一下,BLEclassic bluetooth 有什么关系吗? BLE无法检测到经典蓝牙有什么限制吗?核心蓝牙是否包含BLE和经典蓝牙? @Paulw11 iOS 应用只能通过 Core Bluetooth 看到 BLE 设备。一般来说,应用程序无法发现或使用经典蓝牙设备;针对您的特定应用注册的 MFi 蓝牙设备例外。 【参考方案1】:

扫描将仅检测广告设备。把它想象成一个尖叫着“我在这里!”的设备。如果设备已连接到您的手机,则无需宣传其位置,因此不会出现在您的扫描中。

这就是某些设备的“配对模式”所做的,它会启动广告让其他设备知道它的存在。

您可以下载其他流行的扫描仪,例如 Android 的 nRF,以确认它看到的设备与您正在开发的应用程序相同。

【讨论】:

以上是关于为啥我无法在 SwiftUI 中检测到使用 CoreBluetooh 的其他蓝牙设备?的主要内容,如果未能解决你的问题,请参考以下文章

为啥嵌入到 SwiftUI 表单中的按钮不起作用?

为啥我会在装饰器上使用责任链?

为啥我的井字游戏代码无法检测到有人中奖了?蟒蛇 3

为啥网络库无法检测到何时在 Swift Ios 中重新连接了互联网

为啥我无法检测到我使用 UIKit Dynamics 推离屏幕的 UIView 何时不再可见?

自定义属性包装器无法准确反映我在 SwiftUI 中的 TextField 的状态,知道为啥吗?