附近的蓝牙设备使用Swift 3.0

我正在寻找一种方式来以编程方式列出我的设备发现任何附近的蓝牙设备(发现)。 我一直没有find任何有关在Swift 3.0中执行此调用的信息或教程。 本QA文章讨论了如何使用Swift 1.0find这些设备,并在Xcode 6中编译,而不是最新的版本8。

我尽了最大的努力使我的代码进入1.0的3.0语法,但是在运行下面的代码时,在Playground中没有任何东西被返回:

import Cocoa import IOBluetooth import PlaygroundSupport class BlueDelegate : IOBluetoothDeviceInquiryDelegate { func deviceInquiryComplete(_ sender: IOBluetoothDeviceInquiry, error: IOReturn, aborted: Bool) { aborted print("called") let devices = sender.foundDevices() for device : Any? in devices! { if let thingy = device as? IOBluetoothDevice { thingy.getAddress() } } } } var delegate = BlueDelegate() var inquiry = IOBluetoothDeviceInquiry(delegate: delegate) inquiry?.start() PlaygroundPage.current.needsIndefiniteExecution = true 

使用IOBluetooth正确的方法

以下代码在Xcode版本8.2.1(8C1002),Swift 3.0中完美地工作。 有几行不是必需的,比如deviceInquiryStarted的整个方法。

更新:这些用法仍然工作在Xcode 9.0(9A235)和Swift 4。

操场

 import Cocoa import IOBluetooth import PlaygroundSupport class BlueDelegate : IOBluetoothDeviceInquiryDelegate { func deviceInquiryStarted(_ sender: IOBluetoothDeviceInquiry) { print("Inquiry Started...") //optional, but can notify you when the inquiry has started. } func deviceInquiryDeviceFound(_ sender: IOBluetoothDeviceInquiry, device: IOBluetoothDevice) { print("\(device.addressString!)") } func deviceInquiryComplete(_ sender: IOBluetoothDeviceInquiry!, error: IOReturn, aborted: Bool) { //optional, but can notify you once the inquiry is completed. } } var delegate = BlueDelegate() var ibdi = IOBluetoothDeviceInquiry(delegate: delegate) ibdi?.updateNewDeviceNames = true ibdi?.start() PlaygroundPage.current.needsIndefiniteExecution = true 

项目 – 应用程序使用

 import Cocoa import IOBluetooth import ... class BlueDelegate : IOBluetoothDeviceInquiryDelegate { func deviceInquiryStarted(_ sender: IOBluetoothDeviceInquiry) { print("Inquiry Started...") } func deviceInquiryDeviceFound(_ sender: IOBluetoothDeviceInquiry, device: IOBluetoothDevice) { print("\(device.addressString!)") } } //other classes here: //reference the following outside of any class: var delegate = BlueDelegate() var ibdi = IOBluetoothDeviceInquiry(delegate: delegate) //refer to these specifically inside of any class: ibdi?.updateNewDeviceNames = true ibdi?.start() //recommended under after an action-button press. 

说明

我最初面临的问题是在查询仍在进行中的同时试图访问这些信息。

当我访问它时,在许多不同的场合下,我的游乐场将会挂起,我将被强制从活动监视器强制退出Xcode.app和com.apple.CoreSimulator.CoreSimulatorService 。 我让自己相信,这只是一个游乐场的错误,只是为了了解,一旦查询完成,我的应用程序将崩溃。

正如苹果的API参考指出的那样:

重要提示:不要在代理方法的设备上执行远程名称请求,也不要在使用此对象时执行远程名称请求。 如果您希望在设备上执行自己的远程名称请求,请在停止此对象后执行它们。 如果您不注意此警告,则可能会使您的stream程陷入僵局。

这完全解释了我的问题。 而不是直接从sender.foundDevices()方法(我相信可能没有更新..?)直接询问IOBluetoothDevice信息,我只是使用函数内置的参数来提及它确实是一个IOBluetoothDevice对象,要求打印这些信息。

最后的注意

我希望在Swift中使用IOBluetooth时,我创build的Q / A可以帮助其他有需要的人。 没有任何教程和大量过时的Objective-C代码使得find这些信息非常具有挑战性。 我想感谢@RobNapier在开始时试图find这个谜题的答案。 我还要感谢NotMyName在苹果开发者论坛的post上的回复。

我将在更早的时候探索在iOS设备中使用这个function!