Dear Apple CS,
I’m working with NFC ISO15693 tags using NFCTagReaderSession / NFCISO15693Tag, and I’d like to read these tags in the background if possible.
Is there any way to read this tag type without triggering the system NFC popup that iOS normally shows?
Please note it will not be a public app, the app is meant for internal use for our employees only.
is there an option to submit a special request for this use case?
Thank you in advance!
Drivers
RSS for tagUnderstand the role of drivers in bridging the gap between software and hardware, ensuring smooth hardware functionality.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi!
Following this ticket: https://developer.apple.com/forums/thread/808764?page=1#868010022
Is there any way to use the hardware RFID reading capabilities of an iPhone to read ISO15693 RF tags silently, and without a UI pop-up? Perhaps using other native iOS libraries than the NFC library?
If not, is there a way for a business to request this feature be allowed in internally used apps only?
I have a driver project where I'm opening and closing a connection to a custom driver.
If I do what I think I need to be doing to unmap the memory, when I try to open the service again, it fails. If I skip the step where I do that unmapping, the service opens successfully.
If I call unmap() before trying to call openConnection() again, it will fail with a -308 error return code. If I skip that call to unmap(), it works and I'm able to communicate with my device.
Here's the code where I open the service:
public func openConnection() throws {
guard !isOpen else { return }
// Open device
var connection: io_connect_t = IO_OBJECT_NULL
var result = IOServiceOpen(device, mach_task_self_, 0, &connection)
if result != kIOReturnSuccess {
NSLog("Failed opening device with error: 0x%08x.\n", result);
throw NSError.cdc_kernelReturnErrorWithError(result)
}
defer { IOConnectRelease(connection) }
if device == IO_OBJECT_NULL || connection == IO_OBJECT_NULL {
throw NSError.cdc_kernelReturnErrorWithError(result)
}
let receiveDataMappedMemory = ClientDriverMappedMemory(connection: connection, memoryType: MappedMemoryType_ReceiveDataBuffer)
try receiveDataMappedMemory.map()
let transmitDataMappedMemory = ClientDriverMappedMemory(connection: connection, memoryType: MappedMemoryType_TransmitDataBuffer)
try transmitDataMappedMemory.map()
// Setup async notification
IONotificationPortSetDispatchQueue(dataReceivedPort, dataReceivedQueue)
let callbackPort = IONotificationPortGetMachPort(dataReceivedPort)
let input = DataStruct(foo: 0, bar: 0)
var output = DataStruct(foo: 0, bar: 0)
var outputSize = MemoryLayout<DataStruct>.size
// Trampoline to C function because I don't quite know how to make this work in Swift
result = setupCallback(self, connection, callbackPort, input, &output, &outputSize)
if result != kIOReturnSuccess {
NSLog("Error registering async callback with driver: \(result)");
throw NSError.cdc_kernelReturnErrorWithError(result)
}
self.connection = connection
self.receivedDataMappedMemory = receiveDataMappedMemory
self.transmitDataMappedMemory = transmitDataMappedMemory
}
map() and unmap() functions:
- (BOOL)mapWithError:(NSError **)error
{
error = error ?: &(NSError * __autoreleasing){ nil };
kern_return_t result = IOConnectMapMemory64(self.connection,
self.memoryType,
mach_task_self(),
&_address,
&_size,
kIOMapAnywhere);
if (result != kIOReturnSuccess) {
*error = [NSError cdc_kernelReturnErrorWithError:result];
return NO;
}
self.mapped = YES;
return YES;
}
- (BOOL)unmapWithError:(NSError **)error
{
error = error ?: &(NSError * __autoreleasing){ nil };
kern_return_t result = IOConnectUnmapMemory64(self.connection,
self.memoryType,
mach_task_self(),
_address);
if (result != kIOReturnSuccess) {
*error = [NSError cdc_kernelReturnErrorWithError:result];
return NO;
}
self.mapped = NO;
return YES;
}
Any insights? What all should I be doing to close the service? Why would the unmapping create this issue or what else could the -308 error be indicated has gone wrong?
Hello Everyone,
I encountered an issue with PCI memory access in DriverKit. In my case, BAR0 is not available, but BAR1 is ready for use. Here’s the log output:
!!! ERROR : Failed to get BAR0 info (error: 0xe00002f0). !!!
BAR1 - MemoryIndex: 0x00000000, Size: 0x00040000, Type: 0
Issue Description
When I initially wrote to BAR0 using memoryIndex = 0, it worked successfully:
AME_Address_Write_32(pAMEData, pAMEData->memoryIndex, AME_HOST_INT_MASK_REGISTER, 0x0F);
However, I mistakenly forgot to update memoryIndex to 1 for BAR1. Surprisingly, the write operation still succeeded.
When I fixed memoryIndex = 1 for BAR1, the write operation no longer had any effect. There was no error, but the expected behavior did not occur.
Relevant API (From IOPCIDevice.iig)
/*!
/*!
* @brief Writes a 32-bit value to the PCI device's aperture at a given memory index.
* @discussion This method writes a 32-bit register on the device and returns its value.
* @param memoryIndex An index into the array of ranges assigned to the device.
* @param offset An offset into the device's memory specified by the index.
* @param data A 32-bit value to be written in host byte order.
*/
void
MemoryWrite32(uint8_t memoryIndex,
uint64_t offset,
uint32_t data) LOCALONLY;
Log Output:
Writes to BAR0 (memoryIndex = 0)
AME_Address_Write_32() called
memoryIndex: 0, offset: 0x34, data: 0xf
Wrote data 0xF to offset 52
AME_Address_Write_32() called
memoryIndex: 0, offset: 0xa0, data: 0x1
Wrote data 0x1 to offset 160
AME_Address_Write_32() called
memoryIndex: 0, offset: 0x20, data: 0xffffffff
Wrote data 0xFFFFFFFF to offset 32
Writes to BAR1 (memoryIndex = 1) – No Response
AME_Address_Write_32() called
memoryIndex: 1, offset: 0x34, data: 0xf
No confirmation log, no visible effect.
Questions
What should memoryIndex be set to for BAR1?
The log shows "BAR1 - MemoryIndex: 0x00000000", but should I be using 1 instead?
How can I verify if a write operation to BAR1 is successful?
Is there a way to check if the memory region is actually writable?
Should I use MemoryRead32() to confirm the written value?
Any guidance would be greatly appreciated!
Best Regards,
Charles
Hello everyone,
I’m working on implementing hardware interrupt handling in DriverKit and came across the InterruptOccurred method in IOInterruptDispatchSource. I noticed that its declaration ends with a TYPE macro:
virtual void InterruptOccurred(OSAction* action, uint64_t count, uint64_t time)
TYPE(IOInterruptDispatchSource::InterruptOccurred);
This structure seems similar to how Timer Events are set up, where an event is linked to a callback and triggered by a timer. I’m attempting to use a similar approach, but for hardware-triggered interrupts rather than timer events.
I’m currently in the trial-and-error phase of the implementation, but if anyone has a working example or reference on how to properly implement and register InterruptOccurred, it would be greatly appreciated!
Best regards,
Charles
I'm developing a CarPlay Fueling app with CarPlay entitlement properly configured. While testing, I ran into two issues and would appreciate any guidance:
UserDefaults access while iPhone is locked:
In my CarPlay implementation, I read values from UserDefaults that were previously saved in the iOS app. However, when the iPhone is locked and the CarPlay session is active, it seems that the CarPlay extension cannot read the stored values. Is this the expected behavior? If so, how can I persist and access data across the app and CarPlay reliably?
API calls while iPhone is locked:
The CarPlay interface in my app communicates with a server to display lists and detail views. When the iPhone is locked, are network calls still allowed from the CarPlay extension?
Currently, I do not have any background modes enabled in the app capabilities.
If I enable background modes and implement background network logic to ensure API calls complete properly, would this be considered acceptable usage for CarPlay in App Store review? Or could it raise any rejection concerns during the approval process?
Thanks in advance for your help.
In my app, I want to launch Apple Maps and start turn-by-turn navigation when the user taps a button.
I referred to Apple’s documentation and sample projects and implemented the following code:
if let url = URL(string: "maps://?t=m&amp;amp;daddr=(addr)") {
self.carplayScene?.open(url, options: nil, completionHandler: nil)
}
This works only if Apple Maps has been launched at least once on the iPhone or in the CarPlay environment.
If Apple Maps has never been opened before, it launches the app but does not automatically start navigation.
However, once the user has opened Apple Maps at least once — either on the phone or through CarPlay — then navigation starts as expected from that point on.
Is this behavior expected? Or is it a bug?
Hello,
I have DriverKit SCSI driver (PCI through Thunderbolt). And there is some logic and command which should be send to device in UserAbortTaskRequest method. But I cannot find out a way UserAbortTaskRequest to be called by system, so cannot debug the code inside.
In which cases IOUserSCSIParallelInterfaceController/DriverKit framework calls UserAbortTaskRequest ?
Is there a way to imitate situation (in driver or in some external tool), so that UserAbortTaskRequest be called to debug such case?
Topic:
App & System Services
SubTopic:
Drivers
Hi,
In Linux we have this driver structure where the handlers are defined as below:
static struct file_operations fops =
{
.owner = THIS_MODULE,
.read = etx_read,
.write = etx_write,
.open = etx_open,
.unlocked_ioctl = etx_ioctl,
.release = etx_release,
};
So when the user app calls open() with the appropriate file/device handle "etx_open" in the driver is acalled, etc. However, the Apple driver structure that is exposed to developers is different and it has changed drastically with the DriverKit architecture.
I have some custom requests from the user app where I need to call this ioctl() type requests on my serial port "tty.myusbserial1234". My driver is derived from IOUserUSBSerial and is working fine for all other practical purposes except for such custom requirements.
Has anyone encountered such a problem in MacOS DriverKit and what is the solution or an alternative?
https://developer.apple.com/documentation/driverkit/communicating-between-a-driverkit-extension-and-a-client-app
This gives a different approach, but the serial ports are accessed via open/read/write/close system calls and tcsetattr and other termios functions to set baud-rate and such. So, the above approcah is not suitable for my purpose.
Any ideas/help is very much appreciated.
Thanks.
Topic:
App & System Services
SubTopic:
Drivers
Hi,
we are listed for the MFI program as a licensed manufacturer. We have now started with the IAP3 sample code and the IAP chips to build up a USB communication between our accessory and an iOS device. We are looking for a sample project for the iOS part. Is there some available? The only official I can find is this:
https://developer.apple.com/library/archive/samplecode/EADemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010079
This app is somehow outdated and from 2016. Is there something else available as a starting point? And how does this relate to IOKit since it is available for serial communication on iOS16 as well?
Kind regards,
Hi,
This is the code snippet in my driver for an usb uart device. I am trying to call standard cdc-acm command to set the Line Coding in the device, but fails with this error:
"USBSendSetLineCoding - Failed : 0xe0005000, bytes transferred: 0"
I guess the USB device is returning this error due to incorrect buffer or format. There is no proper documentation on how to use IOMemoryDescriptor when the data has to be passed down in a buffer to the usb stack. (IOUSBHostInterface->DeviceRequest())
Can anyone please point out what is wrong with this code and suggest a right method?
void MyDriver::USBSendSetLineCoding(uint32_t BaudRate, uint8_t StopBits, uint8_t TX_Parity, uint8_t CharLength)
{
kern_return_t ret = kIOReturnSuccess;
LineCoding *lineParms;
uint16_t lcLen = sizeof(LineCoding)-1;
lineParms = (LineCoding *)IOMalloc(lcLen);
if (!lineParms)
{
MyDebugLog("USBSendSetLineCoding - allocate lineParms failed");
return;
}
bzero(lineParms, lcLen);
lineParms->bCharFormat = StopBits - 2;
lineParms->bParityType = TX_Parity - 1;
lineParms->bDataBits = CharLength;
OSSwapBigToHostInt32(BaudRate);
lineParms->dwDTERate = BaudRate;
IOBufferMemoryDescriptor* bufferDescriptor = nullptr;
_controlInterface->CreateIOBuffer(kIOMemoryDirectionOut, lcLen, &bufferDescriptor);
IOMemoryMap *map = nullptr;
bufferDescriptor->CreateMapping(kIOMemoryMapReadOnly, 0, 0, 0, 0, &map);
if(map == nullptr)
{
MyDebugLog("USBSendSetLineCoding - Failed to map memory in CreateMapping\n");
IOFree(lineParms, lcLen);
bufferDescriptor->release();
return;
}
uint64_t ptr = map->GetAddress();
if(!ptr)
{
MyDebugLog("USBSendSetLineCoding - Failed to get Memory Address\n");
IOFree(lineParms, lcLen);
bufferDescriptor->release();
map->release();
return;
}
memcpy(&ptr, lineParms, lcLen);
uint8_t bmRequestType = kIOUSBDeviceRequestDirectionOut | kIOUSBDeviceRequestTypeClass | kIOUSBDeviceRequestRecipientInterface;
uint16_t wValue = 0;
uint16_t wIndex = _bControlInterfaceNumber;
uint16_t bytesTransferred = 0;
ret = _controlInterface->DeviceRequest(bmRequestType, kUSBSET_LINE_CODING, wValue, wIndex, lcLen, bufferDescriptor, &bytesTransferred, 1000);
IOFree(lineParms, lcLen);
map->release();
bufferDescriptor->release();
if (ret != kIOReturnSuccess) {
MyDebugLog("USBSendSetLineCoding - Failed : 0x%x, bytes transferred: %d\n", ret, bytesTransferred);
return;
}
return;
}
I am able to call DeviceRequest() successfully on the same interface for any other setting that requires no data buffer, such as,
"ret = _controlInterface->DeviceRequest(bmRequestType, kUSBSEND_BREAK, wValue, wIndex, 0, NULL, &bytesTransferred, 1000);"
So I think the "bufferDescriptor" is not properly created or the data is not copied correctly in this function for the failure.
"ret = _controlInterface->DeviceRequest(bmRequestType, kUSBSET_LINE_CODING, wValue, wIndex, lcLen, bufferDescriptor, &bytesTransferred, 1000);"
Any help is very much appreciated. Thanks in advance.
Starting with iOS 26, we've noticed that the accessoryImage in CPListItem is not working as expected in CarPlay. Previously, accessoryImage would appear in place of the accessoryType, but now it appears awkwardly next to the detailText, and the image itself is not rendering properly.
We have submitted feedback to Apple multiple times, but the issue still persists in the latest beta releases.
In general, there seem to be several CarPlay UI problems introduced in iOS 26. For example:
In CPPointOfInterestTemplate, the pinImage is displayed at an excessively large size.
Scroll positions in lists behave unexpectedly.
CPInformationTemplate allows infinite scrolling, which seems unintended.
Please take a look into these issues.
Thank you.
I've made a dext and a user client that overrides IOUserSCSIPeripheralDeviceType00, with the object of writing device firmware to the driver. I can gain and relinquish exclusive access to the device, I can call UserReportMediumBlockSize and get back a sensible answer (512).
I can build command parameters with the INQUIRY macro from IOUserSCSIPeripheralDeviceHelper.h and send that command successfully using UserSendCB, and I receive sensible-looking Inquiry data from the device.
However, what I really want to do is send a WriteBuffer command (opcode 0x3B), and that doesn't work. I have yet to put a bus analyzer on it, but I don't think the command goes out on the bus - there's no valid sense data, and the error returned is 0xe00002bc, or kIOReturnError, which isn't helpful.
This is the code I have which doesn't work.
kern_return_t driver::writeChunk(const char * buf, size_t atOffset, size_t length, bool lastOne)
{
DebugMsg("writeChunk %p at %ld for %ld", buf, atOffset, length);
SCSIType00OutParameters outParameters;
SCSIType00InParameters response;
memset(&outParameters, 0, sizeof(outParameters));
memset(&response, 0, sizeof(response));
SetCommandCDB(&outParameters.fCommandDescriptorBlock,
0x3B, // byte 0, opcode WriteBuffer command
lastOne ? 0x0E : 0x0F, // byte 1 mode: E=save deferred, F = download and defer save
0, // byte 2 bufferID
(atOffset >> 16), // byte 3
(atOffset >> 8), // byte 4
atOffset, // byte 5
(length >> 16), // byte 6
(length >> 8), // byte 7
length, // byte 8
0, // control, byte 9
0, 0, 0, 0, 0, 0); // bytes 10..15
outParameters.fLogicalUnitNumber = 0;
outParameters.fBufferDirection = kIOMemoryDirectionOut;
outParameters.fDataTransferDirection = kSCSIDataTransfer_FromInitiatorToTarget;
outParameters.fTimeoutDuration = 1000; // milliseconds
outParameters.fRequestedByteCountOfTransfer = length;
outParameters.fDataBufferAddr = reinterpret_cast<uint64_t>(buf);
uint8_t senseBuffer[255] = {0};
outParameters.fSenseBufferAddr = reinterpret_cast<uint64_t>(senseBuffer);
outParameters.fSenseLengthRequested = sizeof(senseBuffer);
kern_return_t retVal = UserSendCDB(outParameters, &response);
return retVal;
}
We have an IOUserSCSIPeripheralDeviceType00 class DEXT supporting USB attached devices. With some high-capacity drives, the default setPowerState can exceed 20s to complete. This triggers a kernel panic, although this drive behavior is not unexpected.
With a kernel extension implementing similar functionality we see no such problem as it appears from reading of Apple open source the timeout was 100s.
What changes will allow setPowerState to complete without the kernel panic?
kernel panic report excerpt attached.
panic-full-2025-09-04-063127.0003.txt
Hello everyone,
I've encountered a very strange and persistent logging issue with my DriverKit DEXT and would appreciate any insights from the community.
[Problem Summary]
My DriverKit DEXT, along with its companion Swift app, is functionally working perfectly.
I can repeatedly call methods in the DEXT from the app (e.g., a Ping-Pong test and a StaticProcessInbandTask call) and receive the correct response every time.
However, the os_log messages within my IOUserClient subclass are only successfully recorded for the very first set of interactions. After that, all subsequent logs are completely missing.
What's even stranger is that all successfully recorded logs are attributed to the kernel: process, even for purely user-space methods like ExternalMethod.
[Development Environment]
macOS: 15.7.1
Xcode: 16.4
Hardware: MacBook Pro M1
DEXT Logging Macro (Log.h):
#include <os/log.h>
#define Log(fmt, ...) \
do { \
os_log(OS_LOG_DEFAULT, "[%{public}s] " fmt, __FUNCTION__, ##__VA_ARGS__); \
} while (0)
[Steps to Reproduce & Observed Behavior]
The DEXT is successfully loaded via the companion app.
I click the "Ping-Pong" button, then the "Process InBand" button in the app. The app's UI log correctly shows that the request was sent and a successful response was received from the DEXT.
I repeat step 2 multiple times. Each interaction works flawlessly from the app's perspective.
I then use the log show command to export the logs from this period, for example:
log show --last 5m | grep "com.accusys.Acxxx.driver" > dext_logs.txt
Observed Result (Log Content):
In the dext_logs.txt file, I can only see the logs from the very first Ping-Pong and the very first Process InBand call. All subsequent, successful operations leave no trace in the logs.
kernel: (com.accusys.Acxxx.driver.dext) [ExternalMethod] // { ---
kernel: (com.accusys.Acxxx.driver.dext) [ExternalMethod] // --- }
kernel: (com.accusys.Acxxx.driver.dext) [StaticPingPong] // { ---
kernel: (com.accusys.Acxxx.driver.dext) [StaticPingPong] // --- }
kernel: (com.accusys.Acxxx.driver.dext) [ExternalMethod] // { ---
kernel: (com.accusys.Acxxx.driver.dext) [ExternalMethod] // --- }
kernel: (com.accusys.Acxxx.driver.dext) [StaticProcessInbandTask] // { ---
kernel: (com.accusys.Acxxx.driver.dext) [StaticProcessInbandTask] // --- }
<--- END OF FILE (No new logs appear after this point) --->
[Core Questions]
Why are logs in IOUserClient subclass only recorded once? Given the DEXT is clearly still running and processing requests, why would os_log calls only succeed in writing to the system log database on the first interaction?
Why are all logs attributed to the kernel? Why would logs from 100% user-space code like ExternalMethod and StaticPingPong be attributed to the kernel process?
[Solutions Attempted That Did Not Work]
I have verified with ps aux that the DEXT process (com.accusys.Acxxx.driver) is running continuously in the background and has not crashed.
Attempted to force-restart the logging service with sudo killall logd, but the issue persists.
Performed the most thorough reset possible using systemextensionsctl reset followed by a full reboot, then reinstalled the DEXT. The issue remains exactly the same.
Thank you for any possible help or suggestions
Best, Charles
Hi,
On macOS 11 and earlier versions, we provided users with the following script to uninstall our kext driver:
sudo pkgutil --only-files --files com.magewell.ProCapture | tr '\n' '\0' | xargs -n 1 -0 sudo rm -vf
sudo pkgutil --only-dirs --files com.magewell.ProCapture | grep ProCapture[^/]*$ | tr '\n' '\0' | xargs -n 1 -0 sudo rm -rvf
sudo pkgutil --forget com.magewell.ProCapture
sudo kextcache -system-caches
However, this script no longer works on macOS 13 and returns the following error:
It looks like you're trying to update the system caches. As of macOS 11, the personality cache is no longer in use for keeping kext matching information up-to-date. For more information, see `man kmutil`.
This indicates we can no longer use kextcache -system-caches to clear our driver cache. This creates an issue where even after installing the new dext driver, the dext driver cannot run due to the presence of the old kext driver. We've tried various methods but haven't been able to completely uninstall the old kext driver - after every new system update, the old kext reappears.
The specific process is as follows:
This is the sequence I followed in my latest test
- Device is running macOS 13 Ventura w/ 4247 Pro Capture kext driver installed
kmutil inspect | grep -i magewell
- this returns references to the kext files in /Library/Extensions, which is expected because I have not yet removed the 4247 kext driver
- then I ran the following combination of your removal script and my removal steps:
cd /
sudo rm -r /Library/Extensions/ProCaptureDriver.kext
sudo rm -r /Library/Extensions/ProCaptureEvent.kext
sudo rm /System/Volumes/Preboot/*/boot/*/System/Library/Caches/com.apple.kernelcaches/kernelcache.auxkc*
sudo pkgutil --only-files --files com.magewell.ProCapture | tr '\n' '\0' | xargs -n 1 -0 sudo rm -vf
sudo pkgutil --only-dirs --files com.magewell.ProCapture | grep ProCapture[^/]*$ | tr '\n' '\0' | xargs -n 1 -0 sudo rm -rvf
sudo pkgutil --forget com.magewell.ProCapture
sudo kextcache --clear-staging
sudo kcditto
sudo kmutil install --update-preboot
sudo shutdown -r now
- After this I ran 'kmutil inspect | grep -i magewell' and got no results, which seems good but...
- then I ran the upgrade to macOS 15.7 Sequoia
- Afterwards I ran 'kmutil inspect | grep -i magewell' and it returned references to the old /Library/Extensions kexts again, although the files no longer exist in /Library/Extensions
- I then ran my cleanup process again (slightly different for Sequoia-available commands):
sudo rm /System/Volumes/Preboot/*/boot/*/System/Library/Caches/com.apple.kernelcaches/kernelcache.auxkc*
sudo kextcache --clear-staging
sudo kmutil rebuild
sudo kcditto
sudo kmutil install --update-preboot
sudo shutdown -r now
- Then I ran 'kmutil inspect | grep -i magewell' and got no results again
- As a next test I ran a minor update to macOS 15.7.1, then ran 'kmutil inspect | grep -i magewell' and the references to the old kexts came back again
We have indeed identified a solution to address this issue:
kmutil trigger-panic-medic --volume-root /Volumes/<YourVolumeName>
However, this method requires booting into Recovery Mode, which is unacceptable for many of our customers. Especially for those who need bulk remote management, having personnel physically operate each machine one by one is simply not feasible.
Therefore, is there a method to completely uninstall the kext driver while in normal mode?
Thank you!
I have been working on a multi-platform multi-touch HID-standard digitizer clickpad device.
The device uses Bluetooth Low Energy (BLE) as its connectivity transport and advertises HID over GATT. To date, I have the device working successfully on Windows 11 as a multi-touch, gesture-capable click pad with no custom driver or app on Windows.
However, I have been having difficulty getting macOS to recognize and react to it as a HID-standard multi-touch click pad digitizer with either the standard Apple HID driver (AppleUserHIDEventDriver) or with a custom-coded driver extension (DEXT) modeled, based on the DTS stylus example and looking at the IOHIDFamily open source driver(s).
The trackpad works with full-gesture support on Windows 11 and the descriptors seem to be compliant with the R23 Accessory Guidelines document, §15.
With the standard, matching Apple AppleUserHIDEventDriver HID driver, when enumerating using stock-standard HID mouse descriptors, the device works fine on macOS 14.7 "Sonoma" as a relative pointer device with scroll wheel capability (two finger swipe generates a HID scroll report) and a single button.
With the standard, matching Apple AppleUserHIDEventDriver HID driver, when enumerating using stock-standard HID digitizer click/touch pad descriptors (those same descriptors used successfully on Windows 11), the device does nothing. No button, no cursor, no gestures, nothing. Looking at ioreg -filtb, all of the key/value pairs for the driver match look correct.
Because, even with the Apple open source IOHIDFamily drivers noted above, we could get little visibility into what might be going wrong, I wrote a custom DriverKit/HIDDriverKit driver extension (DEXT) (as noted above, based on the DTS HID stylus example and the open source IOHIDEventDriver.
With that custom driver, I can get a single button click from the click pad to work by dispatching button events to dispatchRelativePointerEvent; however, when parsing, processing, and dispatching HID digitizer touch finger (that is, transducer) events via IOUserHIDEventService::dispatchDigitizerTouchEvent, nothing happens.
If I log with:
% sudo log stream --info --debug --predicate '(subsystem == "com.apple.iohid")'
either using the standard AppleUserHIDEventDriver driver or our custom driver, we can see that our input events are tickling the IOHIDNXEventTranslatorSessionFilter HID event filter, so we know HID events are getting from the device into the macOS HID stack. This was further confirmed with the DTS Bluetooth PacketLogger app. Based on these events flowing in and hitting IOHIDNXEventTranslatorSessionFilter, using the standard AppleUserHIDEventDriver driver or our custom driver, clicks or click pad activity will either wake the display or system from sleep and activity will keep the display or system from going to sleep.
In short, whether with the stock driver or our custom driver, HID input reports come in over Bluetooth and get processed successfully; however, nothing happens—no pointer movement or gesture recognition.
STEPS TO REPRODUCE
For the standard AppleUserHIDEventDriver:
Pair the device with macOS 14.7 "Sonoma" using the Bluetooth menu.
Confirm that it is paired / bonded / connected in the Bluetooth menu.
Attempt to click or move one or more fingers on the touchpad surface.
Nothing happens.
For the our custom driver:
Pair the device with macOS 14.7 "Sonoma" using the Bluetooth menu.
Confirm that it is paired / bonded / connected in the Bluetooth menu.
Attempt to click or move one or more fingers on the touchpad surface.
Clicks are correctly registered. With transducer movement, regardless of the number of fingers, nothing happens.
I have an iPhone 14 Pro. I downloaded the iOS 26 beta and had a SERIOUS error, rendering the phone unusable.
I charged it to 60% and kept it plugged in while updating.
While updating, I restarted several times at the Apple logo, then at the Welcome screen, and it had quite a few bugs with low battery warnings.
When I turned it on, I noticed I had 1% (I thought it was strange).
When it was plugged in, it wouldn't charge; it only had 1% left, and it also restarted every 2 minutes. Off-plugged, it did exactly the same thing.
In the end, I had to go back to iOS 18.5; I had no problems with this version.
Just wanted to check here to see if anyone else is running into the issue of CarPlay not working at all on iOS 26 Beta 1, even with the update on Friday.
I plug my phone in (wired) and CarPlay never shows up. I've seen a Reddit thread where other folks are seeing the same thing.
I am trying to localize the CFBundleDisplayName and OSBundleUsageDescription of a driver that is part of an app.
I am able to use InfoPlist.strings files to localize the Bundle display name for the app, but when I try to use the same file as part of the driver, the name displayed in settings for the app does not change correctly.
In fact, it seems to follow the default language set in the xcode project. If the default language is not included in the suite of InfoPlist.strings files, it seems to take the string from the info.plist file. sometimes it just seems to take the English version regardless of the default language or tablet language.
Has anyone had success with this?