我正在做一个需要蓝牙2.1的项目,我正在尝试制作一个测试客户端来连接到硬件。
因此,我一直在浏览IOBluetooth的“docs”,并成功地广播了SDP服务记录。
打开设备(android)上的连接并将数据写入我的计算机工作(根据远程设备),但我的客户端工具实际上并没有调用通知的选择器.
这是直到我停止客户端程序并再次启动它,在这种情况下,它会立即启动。
关于如何触发通知的文档也很少,不管它们是否是异步的。
我已经绞尽脑汁一周了,有想法吗?
虚拟客户端代码:
BTSocketSession.swift
class BTSocketSession {
var lock : DispatchSemaphore = DispatchSemaphore(value: 0);
var serviceRecord : IOBluetoothSDPServiceRecord? = nil;
var channel : IOBluetoothRFCOMMChannel? = nil;
var notification : IOBluetoothUserNotification? = nil;
var serverID : BluetoothRFCOMMChannelID = 255;
var done = false;
init(serviceRecordPListPath: String) {
print("Loading Service Dictionary...");
let serviceDict : NSMutableDictionary = NSMutableDictionary(contentsOfFile: serviceRecordPListPath)!;
print("Done.");
print("Publishing service...");
self.serviceRecord = IOBluetoothSDPServiceRecord.publishedServiceRecord(with: serviceDict as! [AnyHashable : Any]);
print("Done.");
}
func listen() {
var id = BluetoothRFCOMMChannelID();
self.serviceRecord?.getRFCOMMChannelID(&id);
self.serverID = id;
print(serviceRecord ?? "Derp");
print(id);
self.notification = IOBluetoothRFCOMMChannel.register(forChannelOpenNotifications: self, selector: #selector(self.rfcommChannelOpen(notification:channel:)), withChannelID: id, direction: kIOBluetoothUserNotificationChannelDirectionIncoming);
self.lock.wait();
}
func cancel() {
print("Cancelling service advertisement...");
if (self.serviceRecord == nil) {
self.removeServiceRecord();
self.lock.signal();
print("Done.");
} else {
print("Error: No service broadcasting.");
}
}
private func removeServiceRecord() {
self.serviceRecord?.remove();
self.serviceRecord = nil;
self.notification?.unregister();
self.notification = nil;
}
@objc func rfcommChannelOpen(notification: IOBluetoothUserNotification, channel: IOBluetoothRFCOMMChannel) {
if (self.serverID != channel.getID()) {
return;
}
print("Notification Recieved!!!");
print(channel);
print(notification);
self.done = true;
notification.unregister();
self.removeServiceRecord();
self.channel = channel;
self.lock.signal();
}
}main.swift
func main() {
let q = DispatchQueue(label: "Demo");
let s = DispatchSemaphore(value: 0);
let c = BTSocketSession(serviceRecordPListPath: "/path/to/plist");
q.async {
print("Waiting for connection event...");
c.listen();
print("Done.");
print("Releasing main thread...");
s.signal()
print("Done.");
}
s.wait();
print("Closing channel...");
c.channel?.close();
c.cancel();
print("Done.");
print("Exiting...");
}
main();
print("Wellp");发布于 2017-05-18 19:16:22
已解决:
事实证明,在OSX中创建命令行/无头应用程序时,必须使用RunLoop接口正确注册系统通知,如蓝牙通道打开通知。
解决方案找到了here。
更改:
以下内容允许程序按预期工作。
func main() {
let q = DispatchQueue(label: "Demo");
let c = BTSocketSession(serviceRecordPListPath: "/path/to/plist");
q.async {
print("Waiting for connection event...");
c.listen();
print("Done.");
print("Releasing main thread...");
c.channel.close();
CFRunLoopStop(RunLoop.main.getCFRunLoop());
print("Done.");
}
RunLoop.main.run();
print("Exiting...");
}
main();
print("Wellp");我希望你今天过得愉快!
https://stackoverflow.com/questions/44013128
复制相似问题