Post

Replies

Boosts

Views

Activity

IOBluetoothHandsFreeDevice API confusion
I wonder how one would use IOBluetoothHandsFree APIs to interact from macOS app with a bluetooth device that implements bluetooth hands free profile. My current observation is as follows: IOBluetoothDevice object representing the device correctly identifies it as a hands free device, i.e.: there is a proper record in services array, that matches the kBluetoothSDPUUID16ServiceClassHandsFree uuid, the IOBluetoothDevice handsFreeDevice property returns 1 Attempt to create IOBluetoothHandsFreeDevice using IOBluetoothDevice as described above (i.e. [[IOBluetoothHandsFreeDevice alloc] initWithDevice: myIOBluetoothDeviceThatHasHandsFreeDevicePropertySetTo1 delegate: self]) results in the following output in debugger console: SRS-XB20 is not a hands free device but trying anyways. Subsequent call to connect on an object constructed as above results in the following stream of messages: API MISUSE: <CBClassicPeer: 0x1442447b0 6D801974-5457-9ECE-0A9B-8343EC4F60AA, SRS-XB20, connected, Paired, b8:d5:0b:03:62:70, devType: 19, PID: 0x1582, VID: 0x0039> Invalid RFCOMM CID -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x600003e5de00 SRS-XB20, b8-d5-0b-03-62-70, CID: 0, UUID: 110F > AddInstanceForFactory: No factory registered for id <CFUUID 0x600000b5e3e0> F8BB1C28-BAE8-11D6-9C31-00039315CD46 -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x600003e5de00 SRS-XB20, b8-d5-0b-03-62-70, CID: 0, UUID: 110F > API MISUSE: <CBClassicPeer: 0x1442447b0 6D801974-5457-9ECE-0A9B-8343EC4F60AA, SRS-XB20, connected, Paired, b8:d5:0b:03:62:70, devType: 19, PID: 0x1582, VID: 0x0039> Invalid RFCOMM CID Note that this device's handsFreeServiceRecord looks as follows: ServiceName: Hands-free unit RFCOMM ChannelID: 1 Attributes: { 0 = "uint32(65539)"; 256 = "string(Hands-free unit)"; 9 = "{ { uuid32(00 00 11 1e), uint32(262) } }"; 785 = "uint32(63)"; 1 = "uuid32(00 00 11 1e)"; 6 = "{ uint32(25966), uint32(106), uint32(256) }"; 4 = "{ { uuid32(00 00 01 00) }, { uuid32(00 00 00 03), uint32(1) } }"; } and explicit attempt to open RFCOMM channel no 1 ends like this: WARNING: Unknown error: 911 Failed to open RFCOMM channel -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x6000002036c0 SRS-XB20, b8-d5-0b-03-62-70, CID: 1, UUID: 111E > AddInstanceForFactory: No factory registered for id <CFUUID 0x600003719260> F8BB1C28-BAE8-11D6-9C31-00039315CD46 -[IOBluetoothRFCOMMChannel waitforChanneOpen] CID:1 - timed out waiting to open -[IOBluetoothDevice openRFCOMMChannelSync:withChannelID:delegate:] CID:1 error -536870212 call returned: -536870212
0
0
77
Jun ’25
`sdpQueryComplete:status:` not being called
I try to refresh the SDP data for a Bluetooth device that has reconnected. So when I receive connect notification I call -[IOBluetoothDevice performSDPQuery:] passing object, that should receive the query completion call. What I observe is that sdpQueryComplete:status: is not being called, buit calling performSDPQuery causes additional connect notification to be dispatched. Running this under debugger results in some weird log line: [IOBluetooth] **** This currently won't trigger SDP delegate I run this code on Sequoia 15.5
2
0
59
May ’25
IOBluetooth: discovering if my (classic) bluetooth headset is "connected" to macOS
I want my program to behave differently if a specific bluetooth headset is "connected" to the system. By "connected" I mean that it is: paired with the system appears on a list of audio output in Settings (not necessarily selected as default output) appears on "My Devices" list in Bluetooth preference pane with "Connected" status. I want this to determine "availability" of the device, i.e. likehood that establishing an active connection will succeed. Apparently IOBluetooth does not offer API to easily achieve this... I've tried: [IOBluetooth pairedDevices] to iterate though paired device list. This one correctly returns IOBluetoothDevice object representing my device. When I call [IOBluetoothDevice isConnected] it returns false even though device is listed as "connected" on My Devices list in Bluetooth settings. If I leave the headset at original place, go with my mac to a physically different location and call getLastInqiuryUpdate or recentAccessDate, both return current time, even though the headset is not in range for several days now. So I'm looking to determine the headset "connected" state the same way Bluetooth Settings pane does it and without making an active connection attempt.
0
1
731
Feb ’24
kIOReturnNotPermitted from IOHIDManagerOpen under lldb
I'm writing a C/C++ command line program which, at some point, calls IOHIDManagerOpen. I've added both my program executable and lldb as permitted for input monitoring (as far as I remember, my program was added after showing up a permission prompt, I've added lldb manually later, trying to resolve the problem). My problem is that when I run my program from within lldb in Terminal, the call to IOHIDManagerOpen returns kIOReturnNotPermitted. When I run my program directly in the terminal session (without lldb), this call returns kIOReturnSuccess. Such behaviour means it will be impractical to use lldb for any debugging of this program. What can be done to make lldb session behave the same way, the normal execution works? I'm on: 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:55:06 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6020 arm64 and: lldb-1500.0.200.58 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
2
0
1.2k
Jan ’24
Problem with swift package manager caching and binary package
I've setup my Xcode project to use a binary package, for which the manifest is stored in the private git repository. The dependency tracking is set to branch -- it just fetches the manifest from master branch of the repository. It seems, that after initial fetching Xcode or spm caches the commit hash used to fetch the manifest. If I push an update of Package.swift (i.e. containing updated artifact checksum) this change is not refreshed in the project (i.e. after resetting package cache it complains about the checksum mismatch between the actual binary artifact and the manifest). At the same time if I manually clone the repository I see valid checksum in the manifest. I've tried to use all 3 options in Xcode (i.e. reset package cache, resolve package versions, update to newest version). None of them solves the problem. It seems that to reset the cache I need to remove the package from the project and add it again. I'm looking for an elegant way to refresh the manifest through command line. Currently the only idea I have is to clone the manifest repository manually and overwrite Package.swift in SourcePackages within the projects derived data.
1
0
2.1k
Sep ’22
weird behaviour of UITableView cell recycling
I've got a table view where I'm using [UITableView dequeueReusableCellWithIdentifier:forIndexPath:] to obtain cells. In my test scenario table is static (I do not scroll no change to number of rows etc), but I periodically call reloadData. One of cells is partially off-screen (entire contents of the table view extends beyond height of container view). I'd expect that in such scenario, when I try to dequeue a cell for the same index path and same identifier, I will get the same instance that was used previously, but I noticed that table view tends to return cell previously used at different index path (essentially swapping the cells). Is it an expected, desired behaviour?
2
0
3.2k
Apr ’22
Sandboxed app extensions connecting to not sandboxed XPC service
Hi, I'm developing an macOS app which includes an agent (registered as login item) which is intended to run for entire duration of user's login session. The agent's bundle also includes few application extensions. The application is intended to be distributed outside of App Store. It is not going to be sandboxed but rather notarized, so I'm using hardened runtime. I want to add some application extensions (for example: a file provider etension) to be bundled with the agent. The extensions are sandboxed and belong to the same application group as main application and the agent. Extensions should do some IPC calls on the running agent process. I think the most convenient solution for the IPC would be to use the XPC service, so, in the agent, I'am creating an XPC listener registered to mach service name. Now I want to connect to the XPC service provided by the agent from the app extensions. This, however, fails with the following error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named abcd.service was invalidated: failed at lookup with error 159 - Sandbox restriction." My application bundle has now the following structure: MainApp.app --- main application bundle (hardened runtime) Contents/Library/LoginItems/agent.app --- agent with XPC service (hardened runtime) .../agent.app/Contents/PlugIns/AppExt1.appex --- app extension 1 (sandboxed) .../agent.app/Contents/Plugins/AppExt2.appex --- app extension 2 (sandboxed) Searching through the forum I've found another post, which advises to bundle the XPC service within the app extension to mitigate this issue. This, however, does not seem like a viable solution for my problem: what I need is to call the code on the running agent instance. As an alternative I considered to create a unix domain socket in the application group container and use that for communication between the agent and its extensions. XPC however is more convenient so if there is any way to make it working for the above scenario, I would be interested to learn about it.
3
0
3.5k
Apr ’22
macOS file provider error -2001
I've added file provider extension target to my macOS app. From the app I call NSFileProviderManager.add() to add my extension domain. Unfortunately this call fails with a mysterious error message: Domain=NSFileProviderErrorDomain Code=-2001 "The application cannot be used right now."  I'm looking for a possible cause for this error. My app is not sandboxed, but extension is. The app and extension share the same application group.
2
0
2.5k
Mar ’22
How to subclass NSLocale for tests
I want to unit test some Swift classes which would take Locale as a parameter and then behave in locale-specific way. It looks like there is no easy way to provide my own locale implementation though. I'd like to avoid swizzling, so I tried to subclass NSLocale, i.e.: class MyLocale: NSLocale { init(myargs: whatever) { // initialize here super.init(localeIdentifier: "C") } } but this crashes in runtime:  -[NSLocale initWithLocaleIdentifier:]: method only defined for abstract class. So I re-define that initializer: class MyLocale: NSLocale { override init(localeIdentifier string: String) { // initialize here super.init(localeIdentifier: string) // putting super.init() here doesn't help either } } but the result is the same: but this crashes in runtime:  -[NSLocale initWithLocaleIdentifier:]: method only defined for abstract class. is there any way to properly do what I want without resorting to Objective-C runtime and method swizzling?
2
0
1.1k
Sep ’21
Async/await pattern and stack size
According to this: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html backgroud thread stack size for background threads is 512KB. When using plain old NSThread one control this by using NSThread.stackSize property ( https://developer.apple.com/documentation/foundation/thread/1415190-stacksize ). Is it possible to indicate that asyncDetached {} task requires more stack space than system allocates to background threads by default?
0
0
952
Jun ’21
Automated tests for a complex macOS app
Let's say you are building a non-trivial macOS app. By non-trivial I mean an app consisting of several cooperating compontents (i.e. gGUI app, a command line tool, kexts or pivileged helper tools). What would be your approach to setup an automated testing framework for integration testing of such an app? My current idea is to have a VM image running macOS, expose SSH and vnc access and try to use that as a scripting interface for test execution. What I'm concerned about is interacting with the OS UI (i.e. detecting privileged helper installation dialog and interacting with it), for which probably the way to go would be through VNC which seems like an extremely low level interface to script such an interaction through.
0
0
831
Apr ’21
"Possible race detected. Rejecting." on dlopen(). How to debug?
So I'm building the macOS app, which includes a framework which embeds Python code. Some of the Python modules do dynamically load shared objects. I have put the shared objects under "PlugIns", and there are symlinks from the location where Python expects them to be. I.e.: Python tries to mmap the object from: MySampleApp.app/Contents/Frameworks/MySample.framework/Resources/python/lib/python3.9/site-packages/lxml/etree.cpython-39-darwin.so but this is actually a symlink to: MySampleApp.app/Contents/Frameworks/MySample.framework/Versions/A/PlugIns/site-packages/lxml/etree.cpython-39-darwin.so Both the framework and app are codesigned: % codesign -v -vvv ./MySampleApp.app/ -prepared:/Users/piotr/MySampleApp.app/Contents/MacOS/wl-cli -validated:/Users/piotr/MySampleApp.app/Contents/MacOS/wl-cli -prepared:/Users/piotr/MySampleApp.app/Contents/Library/LoginItems/wlclientd.app -validated:/Users/piotr/MySampleApp.app/Contents/Library/LoginItems/wlclientd.app -prepared:/Users/piotr/MySampleApp.app/Contents/Frameworks/MySample.framework/Versions/Current/. -validated:/Users/piotr/MySampleApp.app/Contents/Frameworks/MySample.framework/Versions/Current/. ./MySampleApp.app/: valid on disk ./MySampleApp.app/: satisfies its Designated Requirement When Python tries to run its code howerer, it fails with the following error message: dlopen(MySampleApp.app/Contents/Frameworks/MySample.framework/Resources/python/lib/python3.9/site-packages/lxml/etree.cpython-39-darwin.so, 2): no suitable image found. Did find: MySampleApp.app/Contents/Frameworks/MySample.framework/Resources/python/lib/python3.9/site-packages/lxml/etree.cpython-39-darwin.so: code signing blocked mmap() of 'MySampleApp.app/Contents/Frameworks/MySample.framework/Resources/python/lib/python3.9/site-packages/lxml/etree.cpython-39-darwin.so' Furthermore, at the time it happens I see the following message in system log: default 09:13:25.897428+0200 kernel MySampleApp.app/Contents/Frameworks/MySample.framework/Versions/A/PlugIns/site-packages/lxml/etree.cpython-39-darwin.so: Possible race detected. Rejecting. What does this message mean exactly and how can I identify the cause of the issue? The same code runs without problems when I disable system integrity protection. The app is not designed for sandboxing. Hardened runtime is enabled.
2
0
1.2k
Apr ’21