12

我正在寻找一种以编程方式列出我的设备找到的附近蓝牙设备(可发现)的方法。我无法找到有关在 Swift 3.0 中执行此调用的任何信息或教程。这篇QA 帖子讨论了使用 Swift 1.0 并在 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
4

1 回答 1

10

正确使用 IOBluetooth

以下代码在 Xcode 版本 8.2.1 (8C1002)、Swift 3.0 中完美运行。有几行不是必需的,例如deviceInquiryStarted.

更新:这些用法在 Xcode 9.2 (9B55) 和 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活动监视器。我让自己相信这只是一个 Playground 错误,只是得知我的应用程序会在查询完成后崩溃。

正如 Apple 的API 参考所述:

重要提示:请勿通过委托方法或在使用此对象时对设备执行远程名称请求。如果您希望在设备上执行自己的远程名称请求,请在停止此对象后执行。如果您不注意此警告,您可能会导致进程死锁。

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

最后说明

我希望我创建的这个 Q/A 在使用IOBluetoothSwift 时可以帮助其他有需要的人。缺乏任何教程和大量过时的 Objective-C 代码使得查找这些信息非常具有挑战性。我要感谢@RobNapier 对试图在一开始就找到这个谜语的答案的支持。我还要感谢 NotMyName 对我在 Apple 开发者论坛上的帖子的回复。

我迟早会在 iOS 设备中探索它的用法!

于 2017-01-30T17:05:56.923 回答