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
I'm developing a CarPlay app and encountered an inconsistent behavior with template detection.
When I present a CPActionSheetTemplate and then print the presentedTemplate property, it returns nil.
However, when I present a CPAlertTemplate, the presentedTemplate property correctly returns the template object.
This inconsistency is causing issues in my app where I need to check if there's already a presented template before showing another one to avoid conflicts.
Why does CPActionSheetTemplate not get detected in presentedTemplate while CPAlertTemplate does? Is this intended behavior or a bug?
Any guidance on how to properly detect if a CPActionSheetTemplate is currently presented would be greatly appreciated.
Hello
I'm testing an 'age range sharing' feature using the AgeRangeService API in an app we service.
I approved 'Age Sharing' during testing.
(For your information, my account is an adult account.)
For repeat testing, I would like to delete the our app from 'Apps that requested user age information' or cancel the sharing status.
However, there doesn't seem to be such a feature.
Is there a way I can't find, or is this a feature that Apple doesn't offer?
We are developing a DriverKit driver on Apple M1. We use the following code to prepare DMA buffer:
IODMACommandSpecification dmaSpecification;
bzero(&dmaSpecification, sizeof(dmaSpecification));
dmaSpecification.options = kIODMACommandSpecificationNoOptions;
dmaSpecification.maxAddressBits = p_dma_mgr->maxAddressBits;
kret = IODMACommand::Create(p_dma_mgr->device,
kIODMACommandCreateNoOptions,
&dmaSpecification,
&impl->dma_cmd
);
if (kret != kIOReturnSuccess) {
os_log(OS_LOG_DEFAULT, "Error: IODMACommand::Create failed! ret=0x%x\n", kret);
impl->user_mem.reset();
IOFree(impl, sizeof(*impl));
return ret;
}
uint64_t flags = 0;
uint32_t segmentsCount = 32;
IOAddressSegment segments[32];
kret = impl->dma_cmd->PrepareForDMA(kIODMACommandPrepareForDMANoOptions,
impl->user_mem.get(),
0,
0, // 0 for entire memory
&flags,
&segmentsCount,
segments
);
if (kret != kIOReturnSuccess) {
OSSafeReleaseNULL(impl->dma_cmd);
impl->user_mem.reset();
IOFree(impl, sizeof(*impl));
os_log(OS_LOG_DEFAULT, "Error: PrepareForDMA failed! ret=0x%x\n", kret);
return kret;
}
I allocated several 8K BGRA video frames, each with a size of 141557760 bytes, and prepared the DMA according to the method mentioned above. The process was successful when the number of frames was 15 or fewer. However, issues arose when allocating 16 frames:
Error: PrepareForDMA failed! ret=0xe00002bd
By calculating, I found that the total size of 16 video frames exceeds 2GB. Is there such a limitation in DriverKit that the total DMA size cannot exceed 2GB? Are there any methods that would allow me to bypass this restriction so I can use more video frame buffers?
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.
Hi all,
We are migrating a SCSI HBA driver from KEXT to DriverKit (DEXT), with our DEXT inheriting from IOUserSCSIParallelInterfaceController. We've encountered a data corruption issue that is reliably reproducible under specific conditions and are hoping for some assistance from the community.
Hardware and Driver Configuration:
Controller: LSI 3108
DEXT Configuration: We are reporting our hardware limitations to the framework via the UserReportHBAConstraints function, with the following key settings:
// UserReportHBAConstraints...
addConstraint(kIOMaximumSegmentAddressableBitCountKey, 0x20); // 32-bit
addConstraint(kIOMaximumSegmentCountWriteKey, 129);
addConstraint(kIOMaximumByteCountWriteKey, 0x80000); // 512KB
Observed Behavior: Direct I/O vs. Buffered I/O
We've observed that the I/O behavior differs drastically depending on whether it goes through the system file cache:
1. Direct I/O (Bypassing System Cache) -> 100% Successful
When we use fio with the direct=1 flag, our read/write and data verification tests pass perfectly for all file sizes, including 20GB+.
2. Buffered I/O (Using System Cache) -> 100% Failure at >128MB
Whether we use the standard cp command or fio with the direct=1 option removed to simulate buffered I/O, we observe the exact same, clear failure threshold:
Test Results:
File sizes ≤ 128MB: Success. Data checksums match perfectly.
File sizes ≥ 256MB: Failure. Checksums do not match, and the destination file is corrupted.
Evidence of failure reproduced with fio (buffered_integrity_test.fio, with direct=1 removed):
fio --size=128M buffered_integrity_test.fio -> Test Succeeded (err=0).
fio --size=256M buffered_integrity_test.fio -> Test Failed (err=92), reporting the following error, which proves a data mismatch during the verification phase:
verify: bad header ... at file ... offset 1048576, length 1048576
fio: ... error=Illegal byte sequence
Our Analysis and Hypothesis
The phenomenon of "Direct I/O succeeding while Buffered I/O fails" suggests the problem may be related to the cache synchronization mechanism at the end of the I/O process:
Our UserProcessParallelTask_Impl function correctly handles READ and WRITE commands.
When cp or fio (buffered) runs, the WRITE commands are successfully written to the LSI 3108 controller's onboard DRAM cache, and success is reported up the stack.
At the end of the operation, to ensure data is flushed to disk, the macOS file system issues an fsync, which is ultimately translated into a SYNCHRONIZE CACHE SCSI command (Opcode 0x35 or 0x91) and sent to our UserProcessParallelTask_Impl.
We hypothesize that our code may not be correctly identifying or handling this SYNCHRONIZE CACHE opcode. It might be reporting "success" up the stack without actually commanding the hardware to flush its cache to the physical disk.
The OS receives this "success" status and assumes the operation is safely complete.
In reality, however, the last batch of data remains only in the controller's volatile DRAM cache and is eventually lost.
This results in an incomplete or incorrect file tail, and while the file size may be correct, the data checksum will inevitably fail.
Summary
Our DEXT driver performs correctly when handling Direct I/O but consistently fails with data corruption when handling Buffered I/O for files larger than 128MB. We can reliably reproduce this issue using fio with the direct=1 option removed.
The root cause is very likely the improper handling of the SYNCHRONIZE CACHE command within our UserProcessParallelTask. P.S. This issue did not exist in the original KEXT version of the driver.
We would appreciate any advice or guidance on this issue.
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.
Kevin's Guide to DEXT Signing
The question of "How do I sign a DEXT" comes up a lot, so this post is my attempt to describe both what the issue are and the best current solutions are. So...
The Problems:
When DEXTs were originally introduced, the recommended development signing process required disabling SIP and local signing. There is a newer, much simpler process that's built on Xcode's integrated code-signing support; however, that newer process has not yet been integrated into the documentation library. In addition, while the older flow still works, many of the details it describes are no longer correct due to changes to Xcode and the developer portal.
DriverKit's use of individually customized entitlements is different than the other entitlements on our platform, and Xcode's support for it is somewhat incomplete and buggy. The situation has improved considerably over time, particularly from Xcode 15 and Xcode 16, but there are still issues that are not fully resolved.
To address #1, we introduced "development" entitlement variants of all DriverKit entitlements. These entitlement variants are ONLY available in development-signed builds, but they're available on all paid developer accounts without any special approval. They also allow a DEXT to match against any hardware, greatly simplifying working with development or prototype hardware which may not match the configuration of a final product.
Unfortunately, this also means that DEXT developers will always have at least two entitlement variants (the public development variant and the "private" approved entitlement), which is what then causes the problem I mentioned in #2.
The Automatic Solution:
If you're using Xcode 16 or above, then Xcode's Automatic code sign support will work all DEXT Families, with the exception of distribution signing the PCI and USB Families.
For completeness, here is how that Automatic flow should work:
Change the code signing configuration to "Automatic".
Add the capability using Xcode.
If you've been approved for one of these entitlements, the one oddity you'll see is that adding your approved capability will add both the approved AND the development variant, while deleting either will delete both. This is a visual side effect of #2 above; however, aside from the exception described below, it can be ignored.
Similarly, you can sign distribution builds by creating a build archive and then exporting the build using the standard Xcode flow.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware
Have a 2019 Ford Edge w/ Sync 3.4, wired carplay. Worked fine w/ iPhone 16 Pro on iOS 18. Upgraded to iPhone 17 Pro, came w/ iOS 26, carplay hasn't worked since.
I've kept trying throughout new iOS 26 releases, lately with iOS 26.3 Public Beta 1, still not working.
Have a long running issue with updates and system diagnostics as I've tried over the last few months: FB20739050
There is also a Apple support community thread with issues like this (and a ton of others) - my first post there was https://discussions.apple.com/thread/256138283?answerId=261613103022&sortBy=oldest_first#261613103022
I'm hoping here in the developer forums someone can maybe take a look at the feedback item and various system diagnostics to pin-point the issue. I'm a little concerned it's still not fixed this far into the follow-up point releases of iOS 26.
Appreciate any help, thanks!
--Chuck
Why hasn't the watchOS app updated immediately after the iPhone app was updated? It remains stuck in "Installing" status on the Apple Watch.
Topic:
App & System Services
SubTopic:
Drivers
Hello everyone,
We are migrating a KEXT storage driver to DriverKit. In our KEXT, we use a "one LUN = one Target" model and successfully create multiple targets in a loop during initialization. We are now trying to replicate this architecture in our DEXT.
The issue is that only Target 0 is fully probed and mounted. For Target 1, the lifecycle silently stops after the first TEST UNIT READY command is successfully acknowledged. The macOS SCSI layer never sends any subsequent probe commands (like INQUIRY) to this target.
The failure sequence for Target 1, observed from our logs (regardless of whether Target 0 is created), is as follows:
AsyncCreateTargetForID(1) -> UserInitializeTargetForID(1) (Succeeds)
UserProcessParallelTask(Target: 1, Opcode: TUR) (Succeeds)
The DEXT correctly acknowledges the TUR command for Target 1 by returning kSCSITaskStatus_CHECK_CONDITION with UNIT ATTENTION in the Sense Data (Succeeds)
<-- Breakpoint -->
UserProcessParallelTask(Target: 1, Opcode: INQUIRY) (Never happens)
Through log comparison, we have confirmed that the DEXT's response to the TUR command for Target 1 is identical to the successful KEXT's response.
We have tried creating only Target 1 (skipping Target 0 entirely), but the behavior is exactly the same -> the probe still stalls after the TUR.
We initially suspected a race condition caused by consecutive calls to AsyncCreateTargetForID(). We attempted several methods to ensure that targets are created sequentially, such as trying to build a "creation chain" using OSAction completion handlers. However, these attempts were unsuccessful due to various compilation errors and API misunderstandings.
In any case, this "race condition" theory was ultimately disproven by our experiment where creating only Target 1 still resulted in failure.
We would like to ask two questions:
Is our inability to have a Target ID greater than 0 fully probed by macOS a bug in our own code, or could there be another reason we are unaware of?
If we do indeed need a "one-after-another" creation mechanism for AsyncCreateTargetForID, what is the correct way to implement a "chained creation" using OSAction completion handlers in DriverKit?
Thank you for any help or guidance.
Best Regards,
Charles
Hello!
I have app (macos and iPadOS platforms) with empbedded DEXT. The DEXT executable runs fine on both platforms (ver 26.2).
Trying to execute from iPad App code:
let sysExtWs = OSSystemExtensionsWorkspace.shared
let sysExts = try sysExtWs.systemExtensions(forApplicationWithBundleID: appBudleId)
but always getting OSSystemExtensionError.Code.missingEntitlement error.
Which entitlement am I missing?
Thank You!
I created a custom class that inherits from IOUserSCSIPeripheralDeviceType00 in the DriverKit SCSIPeripheralsDriverKit framework.
When I attempted to send a vendor-specific command to a USB storage device using the UserSendCDB function of this class instance, the function returned the error:
kIOReturnNotPrivileged (iokit_common_err(0x2c1)) // privilege violation
However, when using UserSendCDB in the same way to issue standard SCSI commands such as INQUIRY or Test Unit Ready, no error occurred and the returned sense data was valid.
Why is UserSendCDB able to send standard SCSI commands successfully, but vendor-specific commands return kIOReturnNotPrivileged?
Is there any required entitlement, DriverKit capability, or implementation detail needed to allow vendor-specific CDBs?
Below are the entitlements of my DriverKit extension:
<dict>
<key>com.apple.developer.driverkit.transport.usb</key>
<array>
<dict>
<key>idVendor</key>
<integer>[number of vendorid]</integer>
</dict>
</array>
<key>com.apple.developer.driverkit</key>
<true/>
<key>com.apple.developer.driverkit.allow-any-userclient-access</key>
<true/>
<key>com.apple.developer.driverkit.allow-third-party-userclients</key>
<true/>
<key>com.apple.developer.driverkit.communicates-with-drivers</key>
<true/>
<key>com.apple.developer.driverkit.family.scsicontroller</key>
<true/>
</dict>
If there is any additional configuration or requirement to enable vendor-specific SCSI commands, I would appreciate your guidance.
Environment: macOS15.6 M2 MacBook Pro
I am developing a macOS virtual audio device using an Audio Server Plug-In (HAL). I want the virtual device to be visible to all applications only when my main app is running, and completely hidden from all apps when the app is closed. The goal is to dynamically control device visibility based on app state without reinstalling the driver.What is the recommended way for the app to notify the HAL plug-in about its running or closed state ? Any guidance on best-practice architecture for this scenario would be appreciated.
在Developer app中现在注册按钮时置灰等,无法点击,我发送的联系邮件也没有得到回应,有什么办法解决吗
Topic:
App & System Services
SubTopic:
Drivers
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?
Hello!
We develop a SAS driver and a service application for DAS devices.
When users in our application create a RAID array on the device:
On the 1st step, our dext driver mounts a new volume. At this step DiskUtil automatically tries to mount it. As there is no file system on the new volume - the MacOS system popup appears "The disk you attached was not readable by the computer"
On the 2nd step our application creates the file system on this new volume.
So we do not need this MacOS system popup to appear (as it may frustrate our users).
We found a way to disable the global auto mount but this solution also impacts on other devices (which is not good).
Are there any other possibilities to prevent the popup "The disk you attached was not readable by the computer" from appearing?
1. 环境描述 (Environment)
OS: macOS 26.2
Hardware: Apple Silicon (M1/M2/M3)
DriverKit SDK: DriverKit 19.0 / 20.0
Arch: Universal (x86_64, arm64, arm64e)
SIP Status: Enabled (Works perfectly when Disabled)
2. 问题现象 (Problem Description)
在开启 SIP 的环境下,USB 驱动扩展(Dext)能安装,但插入设备时无法连接设备(驱动的Start方法未被调用)。
驱动状态:
MacBook-Pro ~ % systemextensionsctl list
1 extension(s)
--- com.apple.system_extension.driver_extension (Go to 'System Settings > General > Login Items & Extensions > Driver Extensions' to modify these system extension(s))
enabled active teamID bundleID (version) name [state]
* * JK9U78YRLU com.ronganchina.usbapp.MyUserUSBInterfaceDriver (1.3/4) com.ronganchina.usbapp.MyUserUSBInterfaceDriver [activated enabled]
关键日志证据 (Key Logs)
KernelManagerd: Error Domain=NSPOSIXErrorDomain Code=8 "Exec format error"
Syspolicyd: failed to fetch ... /_CodeSignature/CodeRequirements-1 error=-10
AppleSystemPolicy: ASP: Security policy would not allow process
DriverKit Kernel: DK: MyUserUSBInterfaceDriver user server timeout
dext的
embedded.provisionprofile 已包含:
com.apple.developer.driverkit
com.apple.developer.driverkit.transport.usb (idVendor: 11977)
I am trying to add a few properties to an IOUSBHostDevice but the SetProperties is returning kIOReturnUnsupported. The reason I am trying to modify the IOUSBHostDevice's properties is so we can support a MacBook Air SuperDrive when it is attached to our docking station devices. The MacBook Air SuperDrive needs a high powered port to run and this driver will help the OS realize that our dock can support it.
I see that the documentation for SetProperties says:
The default implementation of this method returns kIOReturnUnsupported. You can override this method and use it to modify the set of properties and values as needed. The changes you make apply only to the current service.
Do I need to override IOUSBHostDevice? This is my current Start implementation (you can also see if in the Xcode project):
kern_return_t
IMPL(MyUserUSBHostDriver, Start)
{
kern_return_t ret = kIOReturnSuccess;
OSDictionary * prop = NULL;
OSDictionary * mergeProperties = NULL;
bool success = true;
os_log(OS_LOG_DEFAULT, "> %s", __FUNCTION__);
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
ret = Start(provider, SUPERDISPATCH);
__Require(kIOReturnSuccess == ret, Exit);
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
ivars->host = OSDynamicCast(IOUSBHostDevice, provider);
__Require_Action(NULL != ivars->host, Exit, ret = kIOReturnNoDevice);
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
ret = ivars->host->Open(this, 0, 0);
__Require(kIOReturnSuccess == ret, Exit);
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
ret = CopyProperties(&prop);
__Require(kIOReturnSuccess == ret, Exit);
__Require_Action(NULL != prop, Exit, ret = kIOReturnError);
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
mergeProperties = OSDynamicCast(OSDictionary, prop->getObject("IOProviderMergeProperties"));
mergeProperties->retain();
__Require_Action(NULL != mergeProperties, Exit, ret = kIOReturnError);
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
OSSafeReleaseNULL(prop);
ret = ivars->host->CopyProperties(&prop);
__Require(kIOReturnSuccess == ret, Exit);
__Require_Action(NULL != prop, Exit, ret = kIOReturnError);
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
os_log(OS_LOG_DEFAULT, "%s : %s", "USB Product Name", ((OSString *) prop->getObject("USB Product Name"))->getCStringNoCopy());
os_log(OS_LOG_DEFAULT, "%s : %s", "USB Vendor Name", ((OSString *) prop->getObject("USB Vendor Name"))->getCStringNoCopy());
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
success = prop->merge(mergeProperties);
__Require_Action(success, Exit, ret = kIOReturnError);
os_log(OS_LOG_DEFAULT, "%s:%d", __FUNCTION__, __LINE__);
ret = ivars->host->SetProperties(prop); // this is no working
__Require(kIOReturnSuccess == ret, Exit);
Exit:
OSSafeReleaseNULL(mergeProperties);
OSSafeReleaseNULL(prop);
os_log(OS_LOG_DEFAULT, "err ref %d", kIOReturnUnsupported);
os_log(OS_LOG_DEFAULT, "< %s %d", __FUNCTION__, ret);
return ret;
}
I'm developing a DriverKit USB driver for iPadOS that needs to communicate with a vendor-class USB device (bInterfaceClass = 0xFF) as I need to communicate with a USB device using a custom protocol over IOUSBHostPipe for bulk transfers.
Current Configuration:
Info.plist: IOProviderClass = IOUSBHostDevice
Device: bDeviceClass = 0, bInterfaceClass = 0xFF (vendor-specific)
What Works:
Driver matches and loads successfully
Start_Impl() executes
device->Open() succeeds
device->SetConfiguration() succeeds
The Problem:
uintptr_t iterRef = 0;
kern_return_t ret = device->CreateInterfaceIterator(&iterRef);
Result: ret = kIOReturnSuccess (0x0), but iterRef = 0 (empty iterator)
What I've Tried:
Matching IOUSBHostInterface directly - Driver is loaded, but extension never executed
Current approach (IOUSBHostDevice) - Driver extension loads and starts, but CreateInterfaceIterator returns empty
Question:
Does iPadOS allow third-party DriverKit extensions to access vendor-class (0xFF) USB devices? That is, iPadOS, is there a way for a third-party DriverKit extension to access IOUSBHostInterface objects for vendor-class (0xFF) USB devices?
Topic:
App & System Services
SubTopic:
Drivers