是否有API可以让您确定Apple Pencil是否已连接到iPad Pro?查看9.1 SDK我没有看到任何直接这样做的东西。或者这可以使用蓝牙API完成。
是否有API可以让您确定Apple Pencil是否已连接到iPad Pro?查看9.1 SDK我没有看到任何直接这样做的东西。或者这可以使用蓝牙API完成。
我在Apple Pencil的蓝牙上找不到任何实际文档 实现(我不相信任何存在),但以下代码工作 for Me™。
它检查自己宣传支持的连接设备 “设备信息”服务,然后如果其中任何一个具有名称“Apple 铅笔”。
@import CoreBluetooth
@interface PencilDetector : NSObject <CBCentralManagerDelegate>
- (instancetype)init;
@end
#include "PencilDetector.h"
@interface PencilDetector ()
@end
@implementation PencilDetector
{
CBCentralManager* m_centralManager;
}
- (instancetype)init
{
self = [super init];
if (self != nil) {
// Save a reference to the central manager. Without doing this, we never get
// the call to centralManagerDidUpdateState method.
m_centralManager = [[CBCentralManager alloc] initWithDelegate:self
queue:nil
options:nil];
}
return self;
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if ([central state] == CBCentralManagerStatePoweredOn)
{
// Device information UUID
NSArray* myArray = [NSArray arrayWithObject:[CBUUID UUIDWithString:@"180A"]];
NSArray* peripherals =
[m_centralManager retrieveConnectedPeripheralsWithServices:myArray];
for (CBPeripheral* peripheral in peripherals)
{
if ([[peripheral name] isEqualToString:@"Apple Pencil"])
{
// The Apple pencil is connected
}
}
}
}
@end
在实践中,以下更简单的同步代码,它不等待
在检查连接的设备之前要打开中央管理器
似乎在我的测试中同样有效。但是,文档说明您不应该这样做
调用管理器上的任何方法,直到状态更新为止
CBCentralManagerStatePoweredOn
,所以较长的代码可能更安全。
m_centralManager = [[CBCentralManager alloc] initWithDelegate:nil
queue:nil
options:nil];
// Device information UUID
NSArray* myArray = [NSArray arrayWithObject:[CBUUID UUIDWithString:@"180A"]];
NSArray* peripherals =
[m_centralManager retrieveConnectedPeripheralsWithServices:myArray];
for (CBPeripheral* peripheral in peripherals)
{
if ([[peripheral name] isEqualToString:@"Apple Pencil"])
{
// The Apple pencil is connected
}
}
我花了很长时间才弄明白CBCentralManager的 centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)
仅在通过其启动连接时调用 connect(_ peripheral: CBPeripheral, options: [String : Any]? = nil)
功能(是的,阅读文档帮助:])。
由于我们没有通过用户将设备连接到设备的回调(就像Apple Pencil的情况一样 - 我很想在这一点上被证明是错误的),我不得不求助于在这里使用计时器。
这是它的工作原理:
初始化时 ApplePencilReachability
设置计时器,每秒检查铅笔的可用性。如果找到铅笔,定时器将失效,如果蓝牙关闭,它也会失效。当它再次打开时,会创建一个新的计时器。
我并不是特别自豪,但它有效:-)
import CoreBluetooth
class ApplePencilReachability: NSObject, CBCentralManagerDelegate {
private let centralManager = CBCentralManager()
var pencilAvailabilityDidChangeClosure: ((_ isAvailable: Bool) -> Void)?
var timer: Timer? {
didSet {
if oldValue !== timer { oldValue?.invalidate() }
}
}
var isPencilAvailable = false {
didSet {
guard oldValue != isPencilAvailable else { return }
pencilAvailabilityDidChangeClosure?(isPencilAvailable)
}
}
override init() {
super.init()
centralManager.delegate = self
centralManagerDidUpdateState(centralManager) // can be powered-on already?
}
deinit { timer?.invalidate() }
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
[weak self] timer in // break retain-cycle
self?.checkAvailability()
if self == nil { timer.invalidate() }
}
} else {
timer = nil
isPencilAvailable = false
}
}
private func checkAvailability() {
let peripherals = centralManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: "180A")])
let oldPencilAvailability = isPencilAvailable
isPencilAvailable = peripherals.contains(where: { $0.name == "Apple Pencil" })
if isPencilAvailable {
timer = nil // only if you want to stop once detected
}
}
}