Corebluetooth on MAC Command Line Application

CoreBluetooth on Mac Command line application

Callbacks in most Apple frameworks are delivered through your application's main run loop. If your command-line tool does not have a run loop, it cannot receive callbacks that are sent this way.

Without a runloop, the only way for the framework to invoke your callback would be to run it on another thread, which could lead to weird behavior in an application that didn't expect that.

It's sufficient to add:

let runLoop = RunLoop.current
let distantFuture = Date.distantFuture
while running == true && runLoop.run(mode: RunLoopMode.defaultRunLoopMode, before: distantFuture) {

}

macOS command line utility vs. CoreBluetooth permissions (iTerm)

Ok, right after setting up the bounty, it occurred to me that all command line apps inherit their permissions from iTerm (which is what I'm using). Granting Bluetooth permission to iTerm makes it just work.

I'd like to slightly adjust the bounty then… is it possible that my command line program can detect this lack of (inherited) permission, thus preventing the crash and rather showing an instruction alert instead?

CoreBluetooth entitlements in Mac App

This seems to have been resolved by changing my code signing entitlements to be correct: I am used to code signing iOS apps and it seems OS X is a whole other question. I had to change my code signing to automatic and developer. And hit the 'Mac App Store' toggle then it worked just fine :)

How to use Core Bluetooth in an OSX app?

I can think of two causes.

  1. You haven't added CoreBluetooth as a linked framework.

  2. You are attempting to run your code in a simulator. The simulator however does not have a Bluetooth device it can use. So you'll have to run all Bluetooth code on a device. I have run across some tutorials about how to use a Bluetooth dongle and get it to work with the simulator, but I've never succeeded.

Also I noticed you haven't set the delegate of the CBCentralManager.

self.centralManager = CBCentralManager(delegate: nil, queue: nil)

Shouldn't that line be,

self.centralManager = CBCentralManager(delegate: self, queue: nil)

MacOS link library containing CoreBluetooth framework

You can just load the library by name in JNA as usual (version 5.6 or greater).

public interface CoreBluetooth extends Library {

CoreBluetooth INSTANCE = Native.load("CoreBluetooth", CoreBluetooth.class);

// mappings
}

You won't find it in the filesystem in macOS 11 or later, however. From the macOS Big Sur 11.0.1 Release Notes:

New in macOS Big Sur 11.0.1, the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem. Code that attempts to check for dynamic library presence by looking for a file at a path or enumerating a directory will fail. Instead, check for library presence by attempting to dlopen() the path, which will correctly check for the library in the cache.

JNA 5.6 was updated to use this new behavior.

That said, I do have a copy of the framework, or at least the header files, on my system under the following path:

/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk/System/Library/Frameworks/CoreBluetooth.framework/

That's not useful for loading into JNA but it does provide header files if the online documentation is insufficient. I'm not sure why you don't have it in your own Command Line tools path or how my installation differs from yours.

How to restore CoreBluetooth's CentralManager state on OSX? Or: Why is CBCentralManagerRestoredStatePeripheralsKey unavailable?

On macOS, apps do not get terminated by the operating system for memory reasons the way they do get terminated on iOS.

When iOS then restores a terminated app, it will also restore the previously connected peripherals to give the iOS app a chance to continue talking to these peripherals.

This said, there's no need on macOS to restore such peripheral connections.

Simulating HID on OSX : IOBluetooth or CoreBluetooth?

CoreBluetooth is for Bluetooth low energy (BLE), whereas IOBluetooth is for classic Bluetooth.
iOS devices can connect to HID devices over either transport: the BLE profile is called HOGP: HID over GATT Profile.

CoreBluetooth/BLE should be easier to work with, but you'll still need to implement the HID protocol yourself.

Note that Apple does prevent iOS applications from publishing HID over GATT but I assume that limitation is not present on OS X.



Related Topics



Leave a reply



Submit