deviceplug / btleplug

Rust Cross-Platform Host-Side Bluetooth LE Access Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

macOs <12 : `Manager::new()` : CBManager authorization objc error

oletf opened this issue · comments

Describe the bug

Problem occurring on call of Manager::new()

Developing an app on a 12.5.1 macOs where the problem doesn't occur.

I've been able to test on a 10.13.6 where I get a panic (foreign exception from rust's POV)
which I've been able to locate to an objc crash happening here :
the error being -[CBManager authorization]: unrecognized selector sent to instance 0x7f9be4601020

According to Apple objc SDK documentation the property went from an instance property to a class property idrk when exactly,
but

both seem to mention that the class property is available since macOS 10.15+ which I don't have access to for now to verify...


Since apparently the CBManager class is available since 10.13 I tried to change the code from :

// CBManager
pub fn manager_authorization() -> CBManagerAuthorization {
    unsafe { msg_send![class!(CBManager), authorization] }
}

to :

// CBManager
pub fn manager_authorization() -> CBManagerAuthorization {
    unsafe {
        let cbmanager: id = msg_send![class!(CBManager), new];
        msg_send![cbmanager, authorization]
    }
}

to get an instance of the class and try to get the legacy authorization property from it.

This change didn't break anything on 12.5, probably because it still gets the class property through the instance in the end.
But on 10.13 it didn't work better...the call to new worked, but the authorization didn't.

I discovered objc rust inter-workings with it on the fly, so I probably missed a thing...

Would anyone else be able to try it on a >=10.13, <12.0 macOs or happen to manage to figure out a better solution ?

Thanks forward

Ok so I just explored previous SDK headers especially 10.13,
and realized that :

  • the CBManager.h only exists since 10.13
  • the authorization property only exists since macOS 10.15 (and the non class property version just existed on iOS 13.0)

So my fix I tried above obviously couldn't work...

What would be the better fix for this ?
Would using os_info to detect macOS version at runtime and having cb::manager_authorization() return :

  • always CBManagerAuthorization::NotDetermined without calling objc CBManager for <10.13
  • using CBManagerState as only available indicator that the CBManager is at least powered on for >=10.13, <10.15
  • as it already is in the current state for >=10.15

make sense ? or any other idea which would fit better in the project ?