Skip to content

Conversation

@timrid
Copy link
Contributor

@timrid timrid commented Oct 29, 2025

This adds support for rubicon-objc to potentially support iOS. Currently I only tested this on macOS and not on iOS.

On macOS it is possible to activate the rubicon-objc framework by setting the environment variable BLEAK_COREBLUETOOTH_FRAMEWORK to rubicon-objc.

I just wanted to share this as a first draft until I actual did tests with an iPhone.

Fixes #1833

@dlech
Copy link
Collaborator

dlech commented Nov 2, 2025

I was hoping for something a bit less invasive to the existing code, e.g. creating a _pyobjc_compat/ folder with modules having the same name and containing classes that have the same API as PyObjC that calls into the equivalent Rubicon API.

Then the existing code would just have to be modified like:

try:
    from CoreBluetooth import CBUUID, ...
except ImportError:
    from ._pyobjc_compat.CoreBluetooth import CBUUID, ...

@timrid
Copy link
Contributor Author

timrid commented Nov 5, 2025

I just borrowed an iPhone to tested this. Unfortunately bluetooth is only available on real iPhones and not in the iOS Simulators. But I can now finally say, that this branch is working flawlessly with briefcase on an iPhone 16 with iOS 26.1.

For the permission handling I had to add this in the pyproject.toml:

[tool.briefcase.app.bleakbleexplorer.iOS]
info."NSBluetoothAlwaysUsageDescription" = "This is your description shown to the user. Explain why the app needs Bluetooth access."

I was hoping for something a bit less invasive to the existing code, e.g. creating a _pyobjc_compat/ folder with modules having the same name and containing classes that have the same API as PyObjC that calls into the equivalent Rubicon API.

Hmm, okay. I'll take a look and see if that makes it clearer. Now that I know it actually works on iOS, I'm motivated to put more work into this topic :)

@timrid
Copy link
Contributor Author

timrid commented Nov 9, 2025

I was hoping for something a bit less invasive to the existing code, e.g. creating a _pyobjc_compat/ folder with modules having the same name and containing classes that have the same API as PyObjC that calls into the equivalent Rubicon API.

Then the existing code would just have to be modified like:

try:
    from CoreBluetooth import CBUUID, ...
except ImportError:
    from ._pyobjc_compat.CoreBluetooth import CBUUID, ...

I was thinking and trying a bit to get a less invasive approach that can be used as your suggestion.

The problem is, that I can not make rubicon-objc directly compatible to pyobjc. So I have to create wrapper around every method and property that bleak is using to adapt the rubicon-objc API to the pypobjc API. Additionally I have to duplicate all the delegates. Currently I have at least 1000 additional lines of code only for the wrappers. I don’t think that it is worth working out a completely new solution for an already running implementation.

Maybe I could split this PR in smaller chunks to simplify the review? Would that be a compromise?

@dlech
Copy link
Collaborator

dlech commented Nov 22, 2025

Maybe I could split this PR in smaller chunks to simplify the review? Would that be a compromise?

Smaller chunks is always helpful.

I think the only thing here that I will really strongly object to is changing the files in typings to be for anything other than PyObjC (fixes are OK, of course).

Rubicon ObjC should have it's own separate typings. I was using it for USB stuff recently and so I have some idea of how I would want to do this, so I don't mind helping with that part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for iOS (add rubicon-objc)

2 participants