Hi
I am building obs studio using cmake and Xcode.
I used
cmake --preset macos -DOBS_CODESIGN_IDENTITY="" to generate the build folder
and inside X code used Provisioning Profile with Developer ID Application certification.
The build was generated successfully but when I tried to turn on the virtual camera I see missing Missing entitlement com.apple.developer.system-extension.install error.
(My Provisioning profile has System Extension Capability checked on apple developer portal)
If I use this flow instead:
cmake --preset macos -DOBS_CODESIGN_TEAM=63B5A5WDNG
Build using Xcode with Automatic manage signing with Apple Developer Certificate.
Obs studio builds successfully and Virtual camera extension also works fine.
My primary goal is to notarise my app which contains OBS studio and Blackhole Audio driver for distribution outside app store.
If I try to sign my obs app generated in second step
codesign --deep --force --timestamp --verify --verbose \
--options runtime
--sign "Developer ID Application:xxx"
"OBS.app"
The obs app fails to launch due to some errors.
Can anyone please guide me which step I might be doing wrong,
Much Appreciated.
Thanks
Extensions
RSS for tagGive users access to your app's functionality and content throughout iOS and macOS using extensions.
Posts under Extensions tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
iOS 26 seems to have changed the way action extension icons appear in the share sheet. My icon is too small now compared to the Copy button in Safari (and Shortcuts’ icons are too small too, a bug?). How do you update it, and how do you ensure it looks fine in iOS 18 and earlier?
My current icon is an AppIcon in the asset catalog, single size 1024x1024, with about 130px padding around it.
I implement a custom keyboard extension. On modern iPhones the dictation button will display in the lower right even when a custom keyboard is active. If you are in an empty text field with the sentence capitalization trait turned on (e.g., Messages), press the Mic button, and dictate something, it will appear with the first word capitalized. As it should. But when you hit the Mic button again to accept the result, the first word is suddenly changed to uncapitalized. With the system keyboard this final case change does not occur.
Why? How to prevent this?
More technical detail: I receive UITextInputDelegate-textWillChange and UITextInputDelegate-textDidChange events during dictation (always with the textInput parameter set to nil) and then a final textDidChange with the lowercased text when accepting at the end.
An XPC service’s process has a system-managed lifecycle: the process is launched on-demand when another process tries to connect to it, and the system can decide to kill it when system resources are low. XPC services can tell the system when they shouldn’t be killed using xpc_transaction_begin/end.
Do extensions created with ExtensionFoundation and/or ExtensionKit have the same behavior?
Hi,
I am developing an iOS app that includes a ReplayKit Broadcast Upload Extension which requires the com.apple.developer.broadcast-upload entitlement.
The app is intended for internal development and testing on my own devices and is not yet distributed on the App Store.
Even after setting com.apple.developer.broadcast-upload=true in my .entitlements file, and linking it in Build Settings > Code Signing Entitlements; my downloaded provisional profile still did not contain the broadcast-upload entitlement.
May I know if I need explicit Apple's approval for adding the broadcast-upload entitlement; even if it's just for testing on my own devices?
Thanks.
Question, if I am writing async code in the notification service extension, I understand it terminates after 30 seconds.
If I want to wait until these async methods finish before calling the content handler, I believe an option I have is to use dispatch groups. However I am open to other solutions if there are better options.
My question is, if I use dispatch groups, is there any issue in using the main queue here? Or does the main thread not make sense to use in the context of the NSE?
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
if (self.contentHandler) {
self.contentHandler(self.bestAttemptContent);
}
});
Or is it recommended to instead use a different queue in the NSE?
dispatch_queue_t nseQueue = dispatch_queue_create("com.blah.blah.nse.queue", DISPATCH_QUEUE_SERIAL);
dispatch_group_notify(group, dispatch_get_global_queue(QOS_CLASS_(SOMETHING), 0), ^{ ... });
OR am I over thinking this? :) Thanks ahead of time, relatively new to iOS so just looking to learn/understand better.
Topic:
App & System Services
SubTopic:
Notifications
Tags:
APNS
Extensions
Notification Center
User Notifications
Hi. My company has a product that has been launched on a web app, a mobile app and an extension in Chrome browser. Currently we are building the extension for Safari, however, we have been rejected.
According to Apple, the reason is that we offer Premium feature inside the extension; however, the extension doesn't offer any purchase option. Has anyone had experience with this? Do we need to develop the purchase function within the Safari extension?
Our product has both Free plan and Premium plan that is subscription-based. We have offered a purchase feature on the website, on the web app, and mobile app
I’m testing .glassEffect() in a widget on the latest iOS 26 beta, but it seems to have no effect at all — the blur isn’t visible, and in some cases even white text disappears completely.
Is this the expected behavior for widgets (i.e. glass effect is not supported), or could this be a bug in the beta?
Would appreciate any clarification or pointers. Thanks!
Is there any supported mechanism in Safari Web Extensions (MV3) for capturing or logging network request data (like fetch, XHR, or webRequest) triggered by the web page?
In a Safari Web Extension using Manifest V3, how can a content script access an HTML file that is bundled with the extension (e.g., to inject it as an iframe)?
Safari's CSP seem to prevent the use of browser.runtime.getURL() in the MAIN world — is there a recommended way to load such resources securely?
I'm trying to make an FSKit module for NTFS read-write filesystem and at the stage where everything is more or less working fine as long as I mount the volume via mount -F and that volume is a RAM disk. However, since the default NTFS read-only driver is already present in macOS, this introduces an additional challenge.
Judging by the DiskArbitration sources, it looks like all FSKit modules are allowed to probe anything only after all kext modules. So, in this situation, any third-party NTFS FSKit module is effectively blocked from using DiskArbitration mechanisms at all because it's always masked during the probing by the system's read-only kext.
This leaves mount -F as the only means to mount the NTFS volume via FSKit. However, even that doesn't work for volumes on real (non-RAM) disks due to permission issues. The logs in Console.app hint that the FSKit extension is running; however, it looks like the fskitd itself doesn't have permissions to access real disks if it's initiated from the mount utility?
default 16:42:41.939498+0200 fskitd New module list <private>
default 16:42:41.939531+0200 fskitd Old modules (null)
default 16:42:41.939578+0200 fskitd Added 2 identifiers: <private>
default 16:42:41.939651+0200 fskitd [0x7fc58020bf00] activating connection: mach=true listener=true peer=false name=com.apple.filesystems.fskitd
debug 16:42:41.939768+0200 fskitd main:RunLoopRun
debug 16:42:41.939811+0200 fskitd -[liveFilesMountServiceDelegate listener:shouldAcceptNewConnection:]: start
default 16:42:41.939870+0200 fskitd Incomming connection, entitled 0
debug 16:42:41.940021+0200 fskitd -[liveFilesMountServiceDelegate listener:shouldAcceptNewConnection:]: accepting connection
default 16:42:41.940048+0200 fskitd [0x7fc580006120] activating connection: mach=false listener=false peer=true name=com.apple.filesystems.fskitd.peer[1816].0x7fc580006120
default 16:42:41.940325+0200 fskitd Hello FSClient! entitlement no
default 16:42:41.940977+0200 fskitd About to get current agent for 503
default 16:42:41.941104+0200 fskitd [0x7fc580015480] activating connection: mach=true listener=false peer=false name=com.apple.fskit.fskit_agent
info 16:42:41.941227+0200 fskitd About to call to fskit_agent
debug 16:42:42.004630+0200 fskitd -[fskitdAgentManager currentExtensionForShortName:auditToken:replyHandler:]_block_invoke: Found extension for fsShortName (<private>)
info 16:42:42.005409+0200 fskitd Probe starting on <private>
debug 16:42:42.005480+0200 fskitd -[FSResourceManager getResourceState:]:not_found:<private>
debug 16:42:42.005528+0200 fskitd -[FSResourceManager addTaskUUID:resource:]:<private>: Adding task (<private>)
debug 16:42:42.005583+0200 fskitd applyResource starting with resource <private> kind 1
default 16:42:42.005609+0200 fskitd About to get current agent for 503
info 16:42:42.005629+0200 fskitd About to call to fskit_agent
debug 16:42:42.006700+0200 fskitd -[fskitdXPCServer getExtensionModuleFromID:forToken:]_block_invoke: Found extension <private>, attrs <private>
default 16:42:42.006829+0200 fskitd About to get current agent for 503
info 16:42:42.006858+0200 fskitd About to call to fskit_agent, bundle ID <private>, instanceUUID <private>
default 16:42:42.070923+0200 fskitd About to grab assertion on pid 1820
default 16:42:42.071058+0200 fskitd Initializing connection
default 16:42:42.071141+0200 fskitd Removing all cached process handles
default 16:42:42.071185+0200 fskitd Sending handshake request attempt #1 to server
default 16:42:42.071223+0200 fskitd Creating connection to com.apple.runningboard
info 16:42:42.071224+0200 fskitd Acquiring assertion: <RBSAssertionDescriptor| "com.apple.extension.session" ID:(null) target:1820>
default 16:42:42.071258+0200 fskitd [0x7fc58001cdc0] activating connection: mach=true listener=false peer=false name=com.apple.runningboard
default 16:42:42.075617+0200 fskitd Handshake succeeded
default 16:42:42.075660+0200 fskitd Identity resolved as osservice<com.apple.filesystems.fskitd>
debug 16:42:42.076337+0200 fskitd Adding assertion 183-1817-1669 to dictionary
debug 16:42:42.076385+0200 fskitd +[FSBlockDeviceResource(Project) openWithBSDName:writable:auditToken:replyHandler:]:bsdName:<private>
default 16:42:42.076457+0200 fskitd [0x7fc5801092e0] activating connection: mach=true listener=false peer=false name=com.apple.fskit.fskit_helper
default 16:42:42.077706+0200 fskitd +[FSBlockDeviceResource(Project) openWithBSDName:writable:auditToken:replyHandler:]_block_invoke: Open device returned error Error Domain=NSPOSIXErrorDomain Code=13
info 16:42:42.077760+0200 fskitd +[FSBlockDeviceResource(Project) openWithBSDName:writable:auditToken:replyHandler:]: failed to open device <private>, Error Domain=NSPOSIXErrorDomain Code=13
default 16:42:42.077805+0200 fskitd [0x7fc5801092e0] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
debug 16:42:42.077830+0200 fskitd +[FSBlockDeviceResource(Project) openWithBSDName:writable:auditToken:replyHandler:]:end
info 16:42:42.078459+0200 fskitd openWith returned err Error Domain=NSPOSIXErrorDomain Code=13 dev (null)
error 16:42:42.078501+0200 fskitd -[fskitdXPCServer getRealResource:auditToken:reply:]: Unable to convert proxy FSBlockDeviceResource into open resource
error 16:42:42.078538+0200 fskitd -[fskitdXPCServer applyResource:targetBundle:instanceID:initiatorAuditToken:authorizingAuditToken:isProbe:usingBlock:]: Can't get the real resource of <private>
default 16:42:42.105443+0200 fskitd [0x7fc580006120] invalidated because the client process (pid 1816) either cancelled the connection or exited
The mount utility call I use is the same for RAM and real disks with the only difference being the device argument and this permission error is only relevant for real disks case.
So, the proper solution (using DiskArbitration) seems to be blocked architecturally in this use case due to FSKit modules being relegated to the fallback role. Is this subject to change in the future?
The remaining workaround with using the mount directly doesn't work for unclear reasons. Is that permission error a bug? Or am I missing something?
My app is designed to share and import images with apps such as the File app. I created a program after looking at various information, but the app from which the images are shared does not work, and the screen cannot be moved to the main screen of my app. The program is as follows. How should I modify it?
import UIKit
import MobileCoreServices
import UniformTypeIdentifiers
class ShareViewController: UIViewController {
let suiteName: String = "group.com.valida.pettyGeneral"
let keyString: String = "share-general"
override func viewDidLoad() {
var nameArray: [String] = [String]()
let sharedDefaults: UserDefaults = UserDefaults(suiteName: self.suiteName)!
guard let inputItem = self.extensionContext?.inputItems.first as? NSExtensionItem, let attachments = inputItem.attachments else {
return
}
let identifier = UTType.image.identifier
let imgAttachments = attachments.filter { $0.hasItemConformingToTypeIdentifier(identifier) }
let dispatchGroup = DispatchGroup()
for (no, itemProvider) in imgAttachments.enumerated() {
dispatchGroup.enter()
itemProvider.loadItem(forTypeIdentifier: identifier, options: nil) { [self] item, error in
do {
if let error = error {
throw error
} else if let url = item as? URL {
let data = try Data(contentsOf: url)
let fileManager = FileManager.default
let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: suiteName)
if let url = url?.appendingPathComponent(String(no)) {
try! data.write(to: url)
}
nameArray.append(String(no))
}
do { dispatchGroup.leave() }
} catch {
print("Error")
do { dispatchGroup.leave() }
}
}
}
dispatchGroup.notify(queue: .main) { [self] in
// 全ての画像を保存
sharedDefaults.set(nameArray, forKey: self.keyString)
sharedDefaults.synchronize()
// メニュー画面に移動する
openUrl(url: URL(string: "container-general://"))
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
}
//#selector(openURL(_:))はこの関数がないと作れない
@objc func open(_ url: URL) {}
func openUrl(url: URL?) {
let selector = #selector(open(_ : ))
var responder = (self as UIResponder).next
while let r = responder, !r.responds(to: selector) {
responder = r.next
}
_ = responder?.perform(selector, with: url)
}
func openContainerApp() {
let url = URL(string: "container-general://") // カスタムスキームを作って指定する
var responder: UIResponder? = self
while responder != nil {
if let application = responder as? UIApplication {
let selector = sel_registerName("openURL:")
application.perform(selector, with: url)
break
}
responder = responder?.next
}
}
}
Hey folks!
I'm working on a macOS app which has a Finder Quick Action extension. It's all working fine, but I'm hitting a weird struggle with getting the icon rendering how I would like, and the docs haven't been able to help me.
I want to re-use a custom SF Symbol from my app, so I've copied that from the main app's xcassets bundle to the one in the extension, and configured it for Template rendering.
The icon renders in the right click menu in Finder, the Finder preview pane and the Extensions section of System Settings, but all of them render with the wrong colour in dark mode. In light mode they look fine, but in dark mode I would expect a templated icon to be rendered in white, not black.
I've attached a variety of screenshots of the icons in the UI and how things are set up in Xcode (both for the symbol in the xcassets bundle, and the Info.plist)
I tried reading the docs, searching Google, searching GitHub and even asking the dreaded AI, but it seems like there's not really very much information available about doing icons for Finder extensions, especially ones using a custom SF Symbol, so I would love to know if anyone here has been able to solve this in the past!
Finder preview pane in light mode:
Finder preview pane in dark mode:
Finder quick action context menu:
System Settings extension preferences:
The custom symbol in my .xcassets bundle:
The finder extension's Info.plist:
I've made working Spotlight Import Extension with in macOS 15.5 (24F74). mdimport confirm it's installed, and working. The problem is related to accessing data inside document bundles (package directory)
class ImportExtension: CSImportExtension {
override func update(_ attributes: CSSearchableItemAttributeSet, forFileAt url: URL) throws {
// ERROR: The file "QuickSort.notepad" couldn't be opened because you don't have permission to view it.
let fileWrapper = try FileWrapper(url: url)
}
}
forFileAt url points to a bundle. In order to read the metadata the extension needs to load the bundle from url and access its content, however in the sandbox environment,t the url allows only access to the bundle directory itself in particular NSFileWrapper(url: url) fails with error "The file "name.extension" couldn't be opened because you don't have permission to view it.", and effectively prevent from providing useful metadata.
Is there a way to access the Document Bundle content in order to read the metadata for Spotlight?
When I use IOKit/usb/IOUSBLib to toggle build-in camera, I got an ERROR:ret IOReturn -536870210
How can I resolve it? Can I use IOUSBLib to disable or hide build-in camera?
My environment:
Model Name: MacBook Pro
ProductVersion: 15.5
Model Identifier: MacBookPro15,2
Processor Name: Quad-Core Intel Core i5
Processor Speed: 2.4 GHz
Number of Processors: 1
// 禁用/启用USB设备
bool toggleUSBDevice(uint16_t vendorID, uint16_t productID, bool enable) {
std::cout << (enable ? "Enabling" : "Disabling") << " USB device with VID: 0x"
<< std::hex << vendorID << ", PID: 0x" << productID << std::endl;
// 创建匹配字典查找指定VID/PID的USB设备
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
if (!matchingDict) {
std::cerr << "Failed to create USB device matching dictionary." << std::endl;
return false;
}
// 设置VID/PID匹配条件
CFNumberRef vendorIDRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &vendorID);
CFNumberRef productIDRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &productID);
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), vendorIDRef);
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), productIDRef);
CFRelease(vendorIDRef);
CFRelease(productIDRef);
// 获取匹配的设备迭代器
io_iterator_t deviceIterator;
if (IOServiceGetMatchingServices(kIOMainPortDefault, matchingDict, &deviceIterator) != KERN_SUCCESS) {
std::cerr << "Failed to get USB device iterator." << std::endl;
CFRelease(matchingDict);
return false;
}
io_service_t usbDevice;
bool result = false;
int deviceCount = 0;
// 遍历所有匹配的设备
while ((usbDevice = IOIteratorNext(deviceIterator)) != IO_OBJECT_NULL) {
deviceCount++;
// 获取设备路径
char path[1024];
if (IORegistryEntryGetPath(usbDevice, kIOServicePlane, path) == KERN_SUCCESS) {
std::cout << "Found device at path: " << path << std::endl;
}
// 打开设备
IOCFPlugInInterface** plugInInterface = NULL;
IOUSBDeviceInterface** deviceInterface = NULL;
SInt32 score;
IOReturn ret = IOCreatePlugInInterfaceForService(
usbDevice,
kIOUSBDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugInInterface,
&score);
if (ret == kIOReturnSuccess && plugInInterface) {
ret = (*plugInInterface)->QueryInterface(plugInInterface,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
(LPVOID*)&deviceInterface);
(*plugInInterface)->Release(plugInInterface);
}
if (ret != kIOReturnSuccess) {
std::cerr << "Failed to open USB device interface. Error:" << ret << std::endl;
IOObjectRelease(usbDevice);
continue;
}
// 禁用/启用设备
if (enable) {
// 启用设备 - 重新配置设备
ret = (*deviceInterface)->USBDeviceReEnumerate(deviceInterface, 0);
if (ret == kIOReturnSuccess) {
std::cout << "Device enabled successfully." << std::endl;
result = true;
} else {
std::cerr << "Failed to enable device. Error: " << ret << std::endl;
}
} else {
// 禁用设备 - 断开设备连接
ret = (*deviceInterface)->USBDeviceClose(deviceInterface);
if (ret == kIOReturnSuccess) {
std::cout << "Device disabled successfully." << std::endl;
result = true;
} else {
std::cerr << "Failed to disable device. Error: " << ret << std::endl;
}
}
// 关闭设备接口
(*deviceInterface)->Release(deviceInterface);
IOObjectRelease(usbDevice);
}
IOObjectRelease(deviceIterator);
if (deviceCount == 0) {
std::cerr << "No device found with specified VID/PID." << std::endl;
return false;
}
return result;
}
It looks like ExtensionKit (and ExtensionFoundation) is fully available on iOS 26 but there is no mention about this in WWDC.
From my testing, it seems as of beta 1, ExtensionKit allows the app from one dev team to launch extension provided by another dev team. Before we start building on this, can someone from Apple help confirm this is the intentional behavior and not just beta 1 thing?
I'm currently trying the traditional mode on the latest beta and the slide-over and the traditional splitview is not available, I would like to ask if it's completely removed or just a minor bug because my automation app rely heavily on this old two feature
Hi all,
I'm trying to add Spotlight support to a macOS app that handles custom virtual machine bundles with the .vpvm extension. I’ve followed the current documentation and used the modern CSImportExtension approach with a Spotlight Importer extension target.
Here’s what I’ve done:
App Info.plist:
Declared com.makeprog.vpvm as a UTI conforming to com.apple.package.
Registered it under UTExportedTypeDeclarations and CFBundleDocumentTypes.
Spotlight Importer Extension:
Added a new macOS target using the Spotlight Import Extension template.
Set the NSExtensionPointIdentifier to com.apple.spotlight.import.
Used CSSupportedContentTypes = com.makeprog.vpvm.
Implemented a minimal update(_ attributes:forFileAt:) method that sets displayName, title, and contentDescription.
Other steps:
Verified that the .appex is embedded under Contents/PlugIns/.
Confirmed it appears in mdimport -e output with correct UTI.
Used mdimport -m -d2 -t /path/to/file.vpvm, but I still get:
Imported '/path/to/file.vpvm' of type 'com.makeprog.vpvm' with no plugIn.
The extension is never invoked. I’ve also tried:
Ensuring the .vpvm file is a valid directory bundle.
Restarting Spotlight / rebuilding index.
Ensuring the app and extension are properly signed.
Tried installing the app in test virtual machine
Question:
Has anyone successfully used CSImportExtension for custom UTIs?
Is there something additional I need to do for the extension to be recognized and triggered?
Any advice or examples would be greatly appreciated!
Thanks in advance.
Hi
We have a non-replicated Files Provider extension on iOS that creates multiple domains. I've noticed that iOS typically creates one process per domain, so I would assume that each process is meant to handle one domain. However, in practice, is seems that calls for any domain can occur in any process.
I'm wondering whether there is supposed to be a mapping, implying there might be something wrong with the code, or whether we shouldn't make assumptions about domain:process mapping.
Thanks for any info you can provide.
I've gotten to the point where I can use the mount(8) command line tool and the -t option to mount a file system using my FSKit file system extension, in which case I can see a process for my extension launch, probe, and perform the other necessary actions.
However, when plugging in my USB flash drive or trying to mount with diskutil mount, the file system does not mount:
$ diskutil mount disk20s3
Volume on disk20s3 failed to mount
If you think the volume is supported but damaged, try the "readOnly" option
$ diskutil mount readOnly disk20s3
Volume on disk20s3 failed to mount
If you think the volume is supported but damaged, try the "readOnly" option
Initially I thought it would be enough to just implement probeExtension(resource:replyHandler:) and the system would handle the rest, but this doesn't seem to be the case. Even a trivial implementation that always returns .usable doesn't cause the system to use my FSModule, even though I've enabled my extension in System Settings > General > Login Items & Extensions > File System Extensions.
From looking at some of the open source msdos and Disk Arb code, it seems like my app extension needs to list FSMediaTypes to probe. I eventually tried putting this in my Info.plist of the app extension:
<key>FSMediaTypes</key>
<dict>
<key>EBD0A0A2-B9E5-4433-87C0-68B6B72699C7</key>
<dict>
<key>FSMediaProperties</key>
<dict>
<key>Content Hint</key>
<string>EBD0A0A2-B9E5-4433-87C0-68B6B72699C7</string>
<key>Leaf</key>
<true/>
</dict>
</dict>
<key>0FC63DAF-8483-4772-8E79-3D69D8477DE4</key>
<dict>
<key>FSMediaProperties</key>
<dict>
<key>Content Hint</key>
<string>0FC63DAF-8483-4772-8E79-3D69D8477DE4</string>
<key>Leaf</key>
<true/>
</dict>
</dict>
<key>Whole</key>
<dict>
<key>FSMediaProperties</key>
<dict>
<key>Leaf</key>
<true/>
<key>Whole</key>
<true/>
</dict>
</dict>
<key>ext4</key>
<dict>
<key>FSMediaProperties</key>
<dict>
<key>Content Hint</key>
<string>ext4</string>
<key>Leaf</key>
<true/>
</dict>
</dict>
</dict>
</plist>
(For reference, the partition represented by disk20s3 has a Content Hint of 0FC63DAF-8483-4772-8E79-3D69D8477DE4 and Leaf is True which I verified using IORegistryExplorer.app from the Xcode additional tools.)
Looking in Console it does appear now that the system is trying to use my module (ExtendFS_fskit) to probe when I plug in my USB drive, but I never see a process for my extension actually launch when trying to attach to it from Xcode by name (unlike when I use mount(8), where I can do this). However I do see a Can't find the extension for <private> error which I'm not sure is related but does sound like the system can't find the extension for some reason.
The below messages are when filtering for "FSKit":
default 19:14:53.455826-0400 diskarbitrationd probed disk, id = /dev/disk20s3, with ExtendFS_fskit, ongoing.
default 19:14:53.456038-0400 fskitd Incomming connection, entitled 1
default 19:14:53.456064-0400 fskitd [0x7d4172e40] activating connection: mach=false listener=false peer=true name=com.apple.filesystems.fskitd.peer[350].0x7d4172e40
default 19:14:53.456123-0400 fskitd Hello FSClient! entitlement yes
default 19:14:53.455902-0400 diskarbitrationd [0x7461d8dc0] activating connection: mach=true listener=false peer=false name=com.apple.filesystems.fskitd
default 19:14:53.456151-0400 diskarbitrationd Setting remote protocol to all XPC
default 19:14:53.456398-0400 fskitd About to get current agent for 501
default 19:14:53.457185-0400 diskarbitrationd probed disk, id = /dev/disk20s3, with ExtendFS_fskit, failure.
error 19:14:53.456963-0400 fskitd -[fskitdXPCServer applyResource:targetBundle:instanceID:initiatorAuditToken:authorizingAuditToken:isProbe:usingBlock:]: Can't find the extension for <private>
(I only see these messages after plugging my USB drive in. When running diskutil mount, I see no messages in the console when filtering by FSKit, diskarbitrationd, or ExtendFS afterward. It just fails.)
Is there a step I'm missing to get this to work, or would this be an FSKit bug/current limitation?