首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通道打开时不触发通道打开通知的IOBluetooth寄存器

通道打开时不触发通道打开通知的IOBluetooth寄存器
EN

Stack Overflow用户
提问于 2017-05-16 23:20:26
回答 1查看 598关注 0票数 1

我正在做一个需要蓝牙2.1的项目,我正在尝试制作一个测试客户端来连接到硬件。

因此,我一直在浏览IOBluetooth的“docs”,并成功地广播了SDP服务记录。

打开设备(android)上的连接并将数据写入我的计算机工作(根据远程设备),但我的客户端工具实际上并没有调用通知的选择器.

这是直到我停止客户端程序并再次启动它,在这种情况下,它会立即启动。

关于如何触发通知的文档也很少,不管它们是否是异步的。

我已经绞尽脑汁一周了,有想法吗?

虚拟客户端代码:

BTSocketSession.swift

代码语言:javascript
复制
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

代码语言:javascript
复制
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");
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-18 19:16:22

已解决:

事实证明,在OSX中创建命令行/无头应用程序时,必须使用RunLoop接口正确注册系统通知,如蓝牙通道打开通知。

解决方案找到了here

更改:

以下内容允许程序按预期工作。

代码语言:javascript
复制
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");

我希望你今天过得愉快!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44013128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档