Files and Storage

RSS for tag

Ask questions about file systems and block storage.

Posts under Files and Storage tag

189 Posts

Post

Replies

Boosts

Views

Activity

Skip FileProvider folders without metadata
I want to traverse my local Google Drive folder to calculate the size of all the files on my drive. I'm not interested in files or directories that are not present locally. I use getattrlistbulk for traversing and it takes way too much time. I think it is because FileProvider tries to download metadata for the directories that are not yet materialised. Is there a way to skip non-materialised directories?
3
0
992
Nov ’25
File Provider : unable to trigger `fetchPartialContents(for:version:request:minimalRange:aligningTo:options:completionHandler:)` when opening files
https://developer.apple.com/documentation/fileprovider/nsfileproviderpartialcontentfetching/3923718-fetchpartialcontents fetchPartialContents(for:version:request:minimalRange:aligningTo:options:completionHandler:) I need to use this function to fetch contents of the files partially. But it seems I'm just unable to receive any callback when i try to open the file via double click on finder. I've tried to open files of different types and sizes but still i'm defaulting back to fetchContents(for:version:request:completionHandler:) . I've been thinking if there are any specific configurations or requirements that i have to meet , so i could trigger this callback function for all the fetch Operations for files ? If No, then where am i going wrong ?
2
0
1k
Nov ’25
Lock Contention in APFS/Kernel?
Hello! Some colleagues and work on Jujutsu, a version control system compatible with git, and I think we've uncovered a potential lock contention bug in either APFS or the Darwin kernel. There are four contributing factors to us thinking this is related to APFS or the Kernel: jj's testsuite uses nextest, a test runner for Rust that spawns each individual test as a separate process. The testsuite slowed down by a factor of ~5x on macOS after jj started using fsync. The slowdown increases as additional cores are allocated. A similar slowdown did not occur on ext4. Similar performance issues were reported in the past by a former Mercurial maintainer: https://gregoryszorc.com/blog/2018/10/29/global-kernel-locks-in-apfs/. My friend and colleague André has measured the test suite on an M3 Ultra with both a ramdisk and a traditional SSD and produced this graph: (The most thorough writeup is the discussion on this pull request.) I know I should file a feedback/bug report, but before I do, I'm struggling with profiling and finding kernel/APFS frames in my profiles so that I can properly attribute the cause of this apparent lock contention. Naively, I ran xctrace record --template 'Time Profiler' --output output.trace --launch /Users/dbarsky/.cargo/bin/cargo-nextest nextest run, and while that detected all processes spawned by nextest, it didn't record all processes as part of the same inspectable profile and didn't really show any frames from the kernel/APFS—I had to select individual processes. So I don't waste people's time and so that I can point a frame/smoking gun in the right system, how can I can use instruments to profile where the kernel and/or APFS are spending its time? Do I need to disable SIP?
9
1
751
Nov ’25
UIDocumentPickerViewController does not allow picking folders on connected servers on iOS26
Hey there, I have an app that allows picking any folder via UIDocumentPickerViewController. Up until iOS18 users were able to pick folders from connected servers (servers connected in the Files app) as well. On iOS26, the picker allows for browsing into the connected servers, but the Select button is greyed out and does nothing when tapped. Is this a known issue? This breaks the whole premise of my file syncronization application.
6
0
299
Nov ’25
Creating an URL bookmark in macOS 26.1 of a Windows NTFS fileshare returns a bookmark with access to the local drive
Since macOS 26.1, creating bookmark data based on a NSOpenPanel URL, does not return the expected bookmark data when the selected source concerns a Windows NTFS fileshare. When the returned data is being resolved, the returned URL points to the local drive of the current Mac. Which is of course super confusing for the user. This issue did not occur in macOS 26.0 and older. In essence, the following code line with 'url' based on an URL from a NSOpenPanel after selecting the root of a Windows NTFS share, creates an incorrect bookmark in macOS 26.1: let bookmark = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil) I have tested this on two different Macs with macOS 26.1 with two different Windows PC both hosting NTFS files shares via SMB. My questions: Have anyone else encountered this issue in macOS 26? Perhaps even with other fileshare types? Is there a workaround or some new project configuration needed in Xcode to get this working?
8
0
237
Nov ’25
Security-scoped bookmarks to external volumes are resolved to /
Users of my different apps started reporting an issue that could be related to the ones discussed in this other post: paths on an external volume, such as one mounted by "NTFS for Mac", or a path on a Synology volume, are "converted" to / (Macintosh HD) after going through "laundry" (creating the security-scoped bookmark, resolving the URL from it and using this new URL instead of the one returned by the open panel). Because of this issue, users of my apps are unable to select external volumes, which renders the different apps more or less useless. I've already received many emails regarding this issue in the past few days. A timely fix or suggestion for a workaround would be much appreciated, so that they don't have to wait for months before the next minor macOS release. The intention of this post is also to show users of my apps that this is a real issue. I created FB21002290 and TSI 16931637.
1
0
197
Nov ’25
How to check if a sandboxed app already has the access permission to a URL
I want to check whether a sandboxed application already has access permission to a specific URL. Based on my investigation, the following FileManager method seems to be able to determine it: FileManager.default.isReadableFile(atPath: fileURL.path) However, the method name and description don't explicitly mention this use case, so I'm not confident there aren't any oversights. Also, since this method takes a String path rather than a URL, I'd like to know if there's a more modern API available. I want to use this information to decide whether to prompt the user about the Sandbox restriction in my AppKit-based app.
5
0
536
Nov ’25
Exact meaning of NSURLBookmarkCreationMinimalBookmark
For bookmark creation and resolving, there's a NSURLBookmark{Creation,Resolution}MinimalBookmark enum value. What does this value imply on macOS and iOS? Specifically, to create security scoped bookmarks on macOS, we use NSURLBookmarkResolutionWithSecurityScope, but that is not available on iOS. Are iOS bookmarks always security scoped? Does the minimal enum imply security scoped bookmarks? Is 0 a valid value to bookmarkDataWithOptions, and does that give an even less scoped bookmark than NSURLBookmarkCreationMinimalBookmark`? We are also using NSURLBookmarkCreationWithoutImplicitSecurityScope on both iOS and macOS, to avoid any implicit resolution of bookmarks we resolve, so that we can explicitly control access by explicit calls to start/stopAccessing. How does NSURLBookmarkCreationWithoutImplicitSecurityScope relate to the enum values discussed above? Thanks! (https://mothersruin.com/software/Archaeology/reverse/bookmarks.html provides some really interesting insights, but doesn't discuss the minimal bookmarks.)
5
1
176
Nov ’25
macOS 26.1 – Severe lag in Open/Save panels when iCloud Drive root contains any items (FileProvider v3 regression)
I’ve filed this as FB20943098 (macOS 26.1 – FileProvider v3 synchronous enumeration bug), but posting here in case others can reproduce and add duplicates. Systems: macOS 26.1 (26B82) M4 Mac mini Pro and M4 MacBook Air Symptoms: In any app (TextEdit, Pages, Browsers, etc.), the Open/Save dialog lags for ~1s per folder navigation click. CPU spikes from fileproviderd, cloudd, bird, and siriactionsd. Key discovery: If my iCloud Drive root is empty (only “Documents” and “Downloads”), performance is perfect. As soon as any folder or file exists at the root of iCloud Drive, the lag returns immediately. Moving those items into “Documents” or “Downloads” makes everything smooth again. Analysis: Based on process traces and container paths, this appears to originate in the FileProvider.framework subsystem (via fileproviderd), which mediates iCloud Drive. Early evidence suggests that folder enumeration of the iCloud Drive container root may be blocking UI threads in macOS 26.1. I believe this may be related to the recent internal migration of the file-provider backend (often referred to as “v3”), but I do not have direct confirmation from Apple of that exact change. MacOS 26.1’s new FileProvider v3 backend seems to be blocking the Open/Save panel while enumerating the iCloud Drive root container (~/Library/Application Support/FileProvider/723EBBFF-…). Folder enumeration seems to wait synchronously for metadata from fileproviderd, and if the local SQLite DB is busy (WAL writes or sync state checks), UI freezes briefly. Workarounds: Disabling iCloud Drive entirely fixes the issue. Simply disabling Desktop/Documents sync does not help. Keeping the iCloud Drive root empty avoids the lag without turning iCloud off. I am able to store whatever I please in the Desktop or Documents folder which is currently syncing. Would appreciate if others on 26.1 could confirm. Engineers: I’ve attached fs_usage, log stream, and process samples to my Feedback ticket via the FB20943098. Expected behavior: Folder enumeration in NSOpenPanel should remain asynchronous regardless of FileProvider background activity. Open/save modal should be responsive and smooth.
6
1
1.7k
Nov ’25
Failed on creating static code object with API SecStaticCodeCreateWithPath(_:_:_:)
My process running with root privilege, but got below error with API SecStaticCodeCreateWithPath(::_:) to create static code object for Cortex XDR Agent app, it working fine for other app like Safari on same device. 2025-07-22 02:02:05.857719(-0600)[23221:520725] DBG Found /Library/Application Support/PaloAltoNetworks/Traps/bin/Cortex XDR Agent.app,/Library/Application Support/PaloAltoNetworks/Traps/bin/Cortex XDR Agent.app running. Will verify the process now 2025-07-22 02:02:05.859209(-0600)[23221:520725] ERR Failed to create static code for path /Library/Application Support/PaloAltoNetworks/Traps/bin/Cortex XDR Agent.app/Contents/MacOS/Cortex XDR Agent. Error: Optional(UNIX[Operation not permitted]) Code Snippet let fileURL = URL(fileURLWithPath: processPath) var code: SecStaticCode? let rc = SecStaticCodeCreateWithPath(fileURL as CFURL, [], &code) if rc == errSecSuccess, let code = code { staticCode = code } else { ZSLoggerError("Failed to create static code for path \(processPath). Error: \(String(describing: SecCopyErrorMessageString(rc, nil)))") return nil }
3
0
151
Nov ’25
`NewDocumentButton(contentType:)` gives "Content serialization failed, document won't be saved."
I'm working on an iOS document-based app. It uses ReferenceFileDocument and custom creation of documents via DocumentGroupLaunchScene + NewDocumentButton. It works fine when I use the plain NewDocumentButton("Whatever") (without any more arguments), but when I want to perform additional setup via preapreDocumentURL or even just add a contentType it gives such output in the console when I hit it: Content serialization failed, document won't be saved. UTType.replayable is correctly wired up in the plist. It looks like a bug in the SDK, but maybe there is a chance that I'm doing something wrong? Here's a code: import SwiftUI import UniformTypeIdentifiers import Combine @main struct MyApp: App { var body: some Scene { DocumentGroup { Document() } editor: { documentConfiguration in EmptyView() } DocumentGroupLaunchScene("Yoyo") { NewDocumentButton(contentType: .replayable) { return URL(string: "whatever, it doesnt even go there...")! } } } } final class Document: ReferenceFileDocument { static var readableContentTypes: [UTType] { [.replayable] } @Published var x = 0 init() {} init(configuration: ReadConfiguration) throws {} func snapshot(contentType: UTType) throws -> Data { Data() } func fileWrapper(snapshot: Data, configuration: WriteConfiguration) throws -> FileWrapper { .init(regularFileWithContents: snapshot) } } extension UTType { static var replayable: UTType { UTType(exportedAs: "com.whatever.yo") } }
2
0
199
Nov ’25
How to detect an auto-mounting directory and wait for it to get mounted?
I need to detect the triggering of an auto-mount operation when accessing the path to a formerly unknown mount point at the file system (BSD, POSIX, NSURL) level, and how to wait for it to finish the operation. Network shares can have sub-volumes on them Consider a Windows server. Let's say there's a SMB sharepoint at C:\Shared. It has some folders, one of which is at C:\Shared\More. Furthermore, there's another partition (volume) on the PC, which is mounted at C:\Shared\More\OtherVol. If you mount the initial share on a Mac with a recent macOS, macOS initially only sees a single mount point at /Volumes/Shared, which can be checked with the "mount" command. Now, if you use Finder to dive into the Shared/More folder, Finder will trigger an auto-mount action on the containing OtherVol folder, and after that, the "mount" command will list two mount points from this server, the second being at /Volumes/Shared/More/OtherVol. (This was a bit surprising to me - I'd have thought that Windows or SMB would hide the fact that the share has sub-volumes, and simply show them as directories - and that's what it did in older macOS versions indeed, e.g. in High Sierra. But in Sequoia, these sub-volumes on the Windows side are mirrored on the Mac side, and they behave accordingly) Browse the volume, including its sub-volumes Now, I have a program that tries to dive into all the folders of this Shared volume, even if it was just freshly mounted and there's no mountpoint at /Volumes/Shared/More/OtherVol known yet (i.e. the user didn't use Finder to explore it). This means, that if my program, e.g. using a simple recursive directory scan, reaches /Volumes/Shared/More/OtherVol, the item will not appear as a volume but as an empty folder. E.g, if I get the NSURLIsVolumeKey value, it'll be false. Only once I try to enter the empty dir, listing its contents, which will return no items, an auto-mount action will get triggered, which will add the mountpoint at the path. So, in order to browse the actual contents of the OtherVol directory, I'd have to detect this auto-mount operation somehow, wait for it to finish mounting, and then re-enter the same directory so that I now see the mounted content. How do I do that? I.e. how do I tell that a dir is actually a auto-mount point and how do I wait for it to get auto-mounted before I continue to browse its contents? Note that newer macOS versions do not use fstab any more, so that's of no help here. Can the DA API help? Do I need to use the old Disk Arbitration functions for this, somehow? I have used the DA framework in the part to prevent auto-mounting, so I imagine I could hook into that handler, and if I get a callback for a mount operation, I could then queue the newly mounted volume for scanning. The problem, however, is that my scanning code may, having only seen an empty directory at the not-yet-mounted mountpoint, already decided that there's nothing there and finished its operation. I'd need some reliable method that lets my recursive scanning code know whether an auto-mount has been triggered and it therefore needs to wait for the DA callback. So, is there some signal that will let me know IMMEDIATELY after entering the empty mountpoint directory that an auto-mount op is on the way? Because I suspect that the DA callbacks come with a delay, and therefore would come too late if I used that as the notifier that I have to wait.
11
0
699
Nov ’25
Trying to remove app groups from my macOS app doesn't seem to work
Hi, a short question really, which boils down to... How do I make sure I have removed all usage of app groups in my Mac app store app, such that the Mac app store agrees I have! Fundamentally, what I'm trying to do is transfer my app to another developer. In previous releases of this app on the App Store, I used a shared app group container to communicate between the main app and it's (embedded) XPC service, but this blocks App Store transfer of the app to another developer. So I came up with another approach for the App and XPC service to communicate (using a URL bookmark for security scoped files to be passed to the XPC service). And then tried various things to get the app store to accept that I'm no longer using app groups. So far with no luck... removed the app groups entitlements by hand from the entitlements files used to sign the main app and the XPC service, respectively. when that didn't work, go into the Developer Portal, find the app ids for the main app and the XPC service, make sure those app ids had the app groups entitlement removed too, created a new provisioning profile for the app, based on this updated app id, downloaded it, rebuilt an app archive using this updated provisioning profile and used it to create another new release on the app store when that didn't work, found and deleted all app app groups in my developer account in the developer portal itself None of the above worked. When I try to transfer the app in App Store Connect, I still see the same message, "You can't transfer this app because of the following reasons: Sandboxed Group Container You can only transfer sandboxed apps that are not sharing a group container." I'm now pretty far from using a shared group container, so I'm puzzled why it still thinks I am? There is one last thing I can try... I noticed over the weekend that even though the entitlement is gone, there's one place in code that may or may not be run on rare occasions (hard to tell) that attempts to open the app group shared container with the code... let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: ...which I think is just returning nil and doing nothing. Potentially the App Store sees that attempted API access for shared group containers and assumes I'm still using app groups (even though there's no entitlement so that call will always be failing)? I can do yet another App Store update and just remove that code. But I want to get to the bottom of why it has been failing all this time. What is App Store Connect / the Mac App Store looking at that makes it think I'm still using app groups? I've tried so many things and don't want to mess users around with another App Store update unless this code above is the actual cause! Cheers p.s. It's a teamID based app group of the form... MY_TEAM_ID.s4a e.g. SWDC5K54B7.s4a
4
0
288
Nov ’25
FileProviderUI prepare method receives internal fileprovider ID list instead of actual itemIdentifier
In the context of a FPUIActionExtensionViewController module the prepare method is defined like this: override func prepare(forAction actionIdentifier: String, itemIdentifiers: [NSFileProviderItemIdentifier]) { So you would expect the itemIdentifiers list to be the item identifier but instead it is a list of the internal fileprovider IDs like: __fp/fs/docID(6595461) So this is a bit problematic because the only way to recover the ID is by using getUserVisibleURL to get the path which is not great. Is there a better way ? Am I missing something ? Thanks,
5
0
364
Nov ’25
Opening two (or more files) with one dialog box (save panel)
I am slowly converting an Objective C with C program to Swift with C. All of my menus and dialog boxes are now in Swift, but files are still opened and closed in Objective C and C. The following code is Objective C and tries to open two files in the same directory with two related names after getting the base of the name from a Save Panel. The code you see was modified by ChatGPT 5.0, and similar code was modified by Claude. Both LLMs wrote code that failed because neither knows how to navigate Apple’s sandbox. Does anybody understand Apple’s sandbox? I eventually want to open more related files and do not want the user to have to click through multiple file dialog boxes. What is the best solution? Are the LLMs just not up to the task and there is a simple solution to the Objective C code? Is this easier in Swift? Other ideas? Thanks in advance for any help. (BOOL)setupOutputFilesWithBaseName:(NSString*)baseName { NSString *outFileNameStr = baseName; if (outFileNameStr == nil || [outFileNameStr length] == 0) { outFileNameStr = @"output"; } // Show ONE save panel for the base filename NSSavePanel *savePanel = [NSSavePanel savePanel]; [savePanel setMessage:@"Choose base name and location for output files\n(Two files will be created: one ending with 'Pkout', one with 'Freqout')"]; [savePanel setNameFieldStringValue:outFileNameStr]; if (directoryURL != nil) { [savePanel setDirectoryURL:directoryURL]; } if ([savePanel runModal] != NSModalResponseOK) { NSLog(@"User cancelled file selection"); return NO; } // Get the selected file URL - this gives us security access to the directory NSURL *baseFileURL = [savePanel URL]; // Get the directory - THIS is what we need for security scope NSURL *dirURL = [baseFileURL URLByDeletingLastPathComponent]; // Start accessing the DIRECTORY, not just the file BOOL didStartAccessing = [dirURL startAccessingSecurityScopedResource]; if (!didStartAccessing) { NSLog(@"Warning: Could not start security-scoped access to directory"); } NSString *baseFileName = [[baseFileURL lastPathComponent] stringByDeletingPathExtension]; NSString *extension = [baseFileURL pathExtension]; // Create the two file names with suffixes NSString *pkoutName = [baseFileName stringByAppendingString:@"Pkout"]; NSString *freqoutName = [baseFileName stringByAppendingString:@"Freqout"]; NSURL *pkoutURL = [dirURL URLByAppendingPathComponent:pkoutName]; NSURL *freqoutURL = [dirURL URLByAppendingPathComponent:freqoutName]; NSLog(@"Attempting to open: %@", [pkoutURL path]); NSLog(@"Attempting to open: %@", [freqoutURL path]); // Open the first file (Pkout) globalFpout = fopen([[pkoutURL path] UTF8String], "w+"); if (globalFpout == NULL) { int errnum = errno; NSLog(@"Error: Could not open Pkout file at %@", [pkoutURL path]); NSLog(@"Error code: %d - %s", errnum, strerror(errnum)); if (didStartAccessing) { [dirURL stopAccessingSecurityScopedResource]; } return NO; } NSLog(@":white_check_mark: Pkout file opened: %@", [pkoutURL path]); // Open the second file (Freqout) globalFpfrqout = fopen([[freqoutURL path] UTF8String], "w+"); if (globalFpfrqout == NULL) { int errnum = errno; NSLog(@"Error: Could not open Freqout file at %@", [freqoutURL path]); NSLog(@"Error code: %d - %s", errnum, strerror(errnum)); fclose(globalFpout); globalFpout = NULL; if (didStartAccessing) { [dirURL stopAccessingSecurityScopedResource]; } return NO; } NSLog(@":white_check_mark: Freqout file opened: %@", [freqoutURL path]); // Store the directory URL so we can stop accessing later secureDirectoryURL = dirURL; return YES; }
0
0
426
Nov ’25
hdiutil prints invisible characters for its devnode output
This script from man hdiutil no longer works: devnode=$(hdiutil attach -nomount ram://102400) newfs_hfs “$devnode” mount -t hfs “$devnode” /path/to/ramdisk because $devnode contains spaces and tabs!! $ hdiutil attach -nomount ram://1 | xxd 00000000: 2f64 6576 2f64 6973 6b34 2020 2020 2020 /dev/disk4 00000010: 2020 2020 0920 2020 2020 2020 2020 2020 . 00000020: 2020 2020 2020 2020 2020 2020 2020 2020 00000030: 2020 2020 090a # remember to clean up afterwards $ hdiutil detach /dev/disk4 Please properly quote your variables in CI test scripts to catch such regression. It could pass because unquoted expansion of $devnode undergoes word splitting after the variable is substituted, removing the trailing whitespaces. FB20303191
1
0
97
Nov ’25
On File System Permissions
Modern versions of macOS use a file system permission model that’s far more complex than the traditional BSD rwx model, and this post is my attempt at explaining that model. If you have a question about this, post it here on DevForums. Put your thread in the App & System Services > Core OS topic area and tag it with Files and Storage. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" On File System Permissions Modern versions of macOS have five different file system permission mechanisms: Traditional BSD permissions Access control lists (ACLs) App Sandbox Mandatory access control (MAC) Endpoint Security (ES) The first two were introduced a long time ago and rarely trip folks up. The second two are newer, more complex, and specific to macOS, and thus are the source of some confusion. Finally, Endpoint Security allows third-party developers to deny file system operations based on their own criteria. This post offers explanations and advice about all of these mechanisms. Error Codes App Sandbox and the mandatory access control system are both implemented using macOS’s sandboxing infrastructure. When a file system operation fails, check the error to see whether it was blocked by this sandboxing infrastructure. If an operation was blocked by BSD permissions or ACLs, it fails with EACCES (Permission denied, 13). If it was blocked by something else, it’ll fail with EPERM (Operation not permitted, 1). If you’re using Foundation’s FileManager, these error are both reported as Foundation errors, for example, the NSFileReadNoPermissionError error. To recover the underlying error, get the NSUnderlyingErrorKey property from the info dictionary. App Sandbox File system access within the App Sandbox is controlled by two factors. The first is the entitlements on the main executable. There are three relevant groups of entitlements: The com.apple.security.app-sandbox entitlement enables the App Sandbox. This denies access to all file system locations except those on a built-in allowlist (things like /System) or within the app’s containers. The various “standard location” entitlements extend the sandbox to include their corresponding locations. The various “file access temporary exceptions” entitlements extend the sandbox to include the items listed in the entitlement. Collectively this is known as your static sandbox. The second factor is dynamic sandbox extensions. The system issues these extensions to your sandbox based on user behaviour. For example, if the user selects a file in the open panel, the system issues a sandbox extension to your process so that it can access that file. The type of extension is determined by the main executable’s entitlements: com.apple.security.files.user-selected.read-only results in an extension that grants read-only access. com.apple.security.files.user-selected.read-write results in an extension that grants read/write access. Note There’s currently no way to get a dynamic sandbox extension that grants executable access. For all the gory details, see this post. These dynamic sandbox extensions are tied to your process; they go away when your process terminates. To maintain persistent access to an item, use a security-scoped bookmark. See Accessing files from the macOS App Sandbox. To pass access between processes, use an implicit security scoped bookmark, that is, a bookmark that was created without an explicit security scope (no .withSecurityScope flag) and without disabling the implicit security scope (no .withoutImplicitSecurityScope flag)). If you have access to a directory — regardless of whether that’s via an entitlement or a dynamic sandbox extension — then, in general, you have access to all items in the hierarchy rooted at that directory. This does not overrule the MAC protection discussed below. For example, if the user grants you access to ~/Library, that does not give you access to ~/Library/Mail because the latter is protected by MAC. Finally, the discussion above is focused on a new sandbox, the thing you get when you launch a sandboxed app from the Finder. If a sandboxed process starts a child process, that child process inherits its sandbox from its parent. For information on what happens in that case, see the Note box in Enabling App Sandbox Inheritance. IMPORTANT The child process inherits its parent process’s sandbox regardless of whether it has the com.apple.security.inherit entitlement. That entitlement exists primarily to act as a marker for App Review. App Review requires that all main executables have the com.apple.security.app-sandbox entitlement, and that entitlements starts a new sandbox by default. Thus, any helper tool inside your app needs the com.apple.security.inherit entitlement to trigger inheritance. However, if you’re not shipping on the Mac App Store you can leave off both of these entitlement and the helper process will inherit its parent’s sandbox just fine. The same applies if you run a built-in executable, like /bin/sh, as a child process. When the App Sandbox blocks something, it might generates a sandbox violation report. For information on how to view these reports, see Discovering and diagnosing App Sandbox violations. To learn more about the App Sandbox, see the various links in App Sandbox Resources. For information about how to embed a helper tool in a sandboxed app, see Embedding a Command-Line Tool in a Sandboxed App. Mandatory Access Control Mandatory access control (MAC) has been a feature of macOS for many releases, but it’s become a lot more prominent since macOS 10.14. There are many flavours of MAC but the ones you’re most likely to encounter are: Full Disk Access (macOS 10.14 and later) Files and Folders (macOS 10.15 and later) App bundle protection (macOS 13 and later) App container protection (macOS 14 and later) App group container protection (macOS 15 and later) Data Vaults (see below) and other internal techniques used by various macOS subsystems Mandatory access control, as the name suggests, is mandatory; it’s not an opt-in like the App Sandbox. Rather, all processes on the system, including those running as root, as subject to MAC. Data Vaults are not a third-party developer opportunity. See this post if you’re curious. In the Full Disk Access and Files and Folders cases, users grant a program a MAC privilege using System Settings > Privacy & Security. Some MAC privileges are per user (Files and Folders) and some are system wide (Full Disk Access). If you’re not sure, run this simple test: On a Mac with two users, log in as user A and enable the MAC privilege for a program. Now log in as user B. Does the program have the privilege? If a process tries to access an item restricted by MAC, the system may prompt the user to grant it access there and then. For example, if an app tries to access the desktop, you’ll see an alert like this: “AAA” would like to access files in your Desktop folder. [Don’t Allow] [OK] To customise this message, set Files and Folders properties in your Info.plist. This system only displays this alert once. It remembers the user’s initial choice and returns the same result thereafter. This relies on your code having a stable code signing identity. If your code is unsigned, or signed ad hoc (Signed to Run Locally in Xcode parlance), the system can’t tell that version N+1 of your code is the same as version N, and thus you’ll encounter excessive prompts. Note For information about how that works, see TN3127 Inside Code Signing: Requirements. The Files and Folders prompts only show up if the process is running in a GUI login session. If not, the operation is allowed or denied based on existing information. If there’s no existing information, the operation is denied by default. For more information about app and app group container protection, see the links in Trusted Execution Resources. For more information about app groups in general, see App Groups: macOS vs iOS: Working Towards Harmony On managed systems the site admin can use the com.apple.TCC.configuration-profile-policy payload to assign MAC privileges. For testing purposes you can reset parts of TCC using the tccutil command-line tool. For general information about that tool, see its man page. For a list of TCC service names, see the posts on this thread. Note TCC stands for transparency, consent, and control. It’s the subsystem within macOS that manages most of the privileges visible in System Settings > Privacy & Security. TCC has no API surface, but you see its name in various places, including the above-mentioned configuration profile payload and command-line tool, and the name of its accompanying daemon, tccd. While tccutil is an easy way to do basic TCC testing, the most reliable way to test TCC is in a VM, restoring to a fresh snapshot between each test. If you want to try this out, crib ideas from Testing a Notarised Product. The MAC privilege mechanism is heavily dependent on the concept of responsible code. For example, if an app contains a helper tool and the helper tool triggers a MAC prompt, we want: The app’s name and usage description to appear in the alert. The user’s decision to be recorded for the whole app, not that specific helper tool. That decision to show up in System Settings under the app’s name. For this to work the system must be able to tell that the app is the responsible code for the helper tool. The system has various heuristics to determine this and it works reasonably well in most cases. However, it’s possible to break this link. I haven’t fully research this but my experience is that this most often breaks when the child process does something ‘odd’ to break the link, such as trying to daemonise itself. If you’re building a launchd daemon or agent and you find that it’s not correctly attributed to your app, add the AssociatedBundleIdentifiers property to your launchd property list. See the launchd.plist man page for the details. Scripting MAC presents some serious challenges for scripting because scripts are run by interpreters and the system can’t distinguish file system operations done by the interpreter from those done by the script. For example, if you have a script that needs to manipulate files on your desktop, you wouldn’t want to give the interpreter that privilege because then any script could do that. The easiest solution to this problem is to package your script as a standalone program that MAC can use for its tracking. This may be easy or hard depending on the specific scripting environment. For example, AppleScript makes it easy to export a script as a signed app, but that’s not true for shell scripts. TCC and Main Executables TCC expects its bundled clients — apps, app extensions, and so on — to use a native main executable. That is, it expects the CFBundleExecutable property to be the name of a Mach-O executable. If your product uses a script as its main executable, you’re likely to encounter TCC problems. To resolve these, switch to using a Mach-O executable. For an example of how you might do that, see this post. Endpoint Security Endpoint Security (ES) is a general mechanism for third-party products to enforce custom security policies on the Mac. An ES client asks ES to send it events when specific security-relevant operations occur. These events can be notifications or authorisations. In the case of authorisation events, the ES client must either allow or deny the operation. As you might imagine, the set of security-relevant operations includes file system operations. For example, when you open a file using the open system call, ES delivers the ES_EVENT_TYPE_AUTH_OPEN event to any interested ES clients. If one of those ES client denies the operation, the open system call fails with EPERM. For more information about ES, see the Endpoint Security framework documentation. Revision History 2025-11-04 Added a discussion of Endpoint Security. Made numerous minor editorial changes. 2024-11-08 Added info about app group container protection. Clarified that Data Vaults are just one example of the techniques used internally by macOS. Made other editorial changes. 2023-06-13 Replaced two obsolete links with links to shiny new official documentation: Accessing files from the macOS App Sandbox and Discovering and diagnosing App Sandbox violations. Added a short discussion of app container protection and a link to WWDC 2023 Session 10053 What’s new in privacy. 2023-04-07 Added a link to my post about executable permissions. Fixed a broken link. 2023-02-10 In TCC and Main Executables, added a link to my native trampoline code. Introduced the concept of an implicit security scoped bookmark. Introduced AssociatedBundleIdentifiers. Made other minor editorial changes. 2022-04-26 Added an explanation of the TCC initialism. Added a link to Viewing Sandbox Violation Reports.  Added the TCC and Main Executables section. Made significant editorial changes. 2022-01-10 Added a discussion of the file system hierarchy. 2021-04-26 First posted.
0
0
12k
Nov ’25
Drag and Drop stopped working after upgrading from macOS 15 to 26
When I drag and drop a file with flag "shouldAttemptToOpenInPlace: true", I was able to access the original file name in macOS 15. After upgrading to macOS 26, I can't access the original file name anymore. Instead, I got some useless file name such as ".com.apple.Foundation.NSItemProvider.gKZ91u.tmp". The app no longer works with these tmp filenames because it needs the orignal file name to do the file transfer. (Btw, this is a WinSCP like app on Mac platform) Could you please check and fix this issue? Thank you. FileRepresentation(contentType: .item, shouldAttemptToOpenInPlace: true)
1
0
404
Nov ’25
Skip FileProvider folders without metadata
I want to traverse my local Google Drive folder to calculate the size of all the files on my drive. I'm not interested in files or directories that are not present locally. I use getattrlistbulk for traversing and it takes way too much time. I think it is because FileProvider tries to download metadata for the directories that are not yet materialised. Is there a way to skip non-materialised directories?
Replies
3
Boosts
0
Views
992
Activity
Nov ’25
TN3150: Getting ready for dataless files
Understand dataless files and how to minimize the performance impact as the system materializes them. View Technote TN3150 >
Replies
1
Boosts
0
Views
1.5k
Activity
Nov ’25
File Provider : unable to trigger `fetchPartialContents(for:version:request:minimalRange:aligningTo:options:completionHandler:)` when opening files
https://developer.apple.com/documentation/fileprovider/nsfileproviderpartialcontentfetching/3923718-fetchpartialcontents fetchPartialContents(for:version:request:minimalRange:aligningTo:options:completionHandler:) I need to use this function to fetch contents of the files partially. But it seems I'm just unable to receive any callback when i try to open the file via double click on finder. I've tried to open files of different types and sizes but still i'm defaulting back to fetchContents(for:version:request:completionHandler:) . I've been thinking if there are any specific configurations or requirements that i have to meet , so i could trigger this callback function for all the fetch Operations for files ? If No, then where am i going wrong ?
Replies
2
Boosts
0
Views
1k
Activity
Nov ’25
Lock Contention in APFS/Kernel?
Hello! Some colleagues and work on Jujutsu, a version control system compatible with git, and I think we've uncovered a potential lock contention bug in either APFS or the Darwin kernel. There are four contributing factors to us thinking this is related to APFS or the Kernel: jj's testsuite uses nextest, a test runner for Rust that spawns each individual test as a separate process. The testsuite slowed down by a factor of ~5x on macOS after jj started using fsync. The slowdown increases as additional cores are allocated. A similar slowdown did not occur on ext4. Similar performance issues were reported in the past by a former Mercurial maintainer: https://gregoryszorc.com/blog/2018/10/29/global-kernel-locks-in-apfs/. My friend and colleague André has measured the test suite on an M3 Ultra with both a ramdisk and a traditional SSD and produced this graph: (The most thorough writeup is the discussion on this pull request.) I know I should file a feedback/bug report, but before I do, I'm struggling with profiling and finding kernel/APFS frames in my profiles so that I can properly attribute the cause of this apparent lock contention. Naively, I ran xctrace record --template 'Time Profiler' --output output.trace --launch /Users/dbarsky/.cargo/bin/cargo-nextest nextest run, and while that detected all processes spawned by nextest, it didn't record all processes as part of the same inspectable profile and didn't really show any frames from the kernel/APFS—I had to select individual processes. So I don't waste people's time and so that I can point a frame/smoking gun in the right system, how can I can use instruments to profile where the kernel and/or APFS are spending its time? Do I need to disable SIP?
Replies
9
Boosts
1
Views
751
Activity
Nov ’25
UIDocumentPickerViewController does not allow picking folders on connected servers on iOS26
Hey there, I have an app that allows picking any folder via UIDocumentPickerViewController. Up until iOS18 users were able to pick folders from connected servers (servers connected in the Files app) as well. On iOS26, the picker allows for browsing into the connected servers, but the Select button is greyed out and does nothing when tapped. Is this a known issue? This breaks the whole premise of my file syncronization application.
Replies
6
Boosts
0
Views
299
Activity
Nov ’25
Creating an URL bookmark in macOS 26.1 of a Windows NTFS fileshare returns a bookmark with access to the local drive
Since macOS 26.1, creating bookmark data based on a NSOpenPanel URL, does not return the expected bookmark data when the selected source concerns a Windows NTFS fileshare. When the returned data is being resolved, the returned URL points to the local drive of the current Mac. Which is of course super confusing for the user. This issue did not occur in macOS 26.0 and older. In essence, the following code line with 'url' based on an URL from a NSOpenPanel after selecting the root of a Windows NTFS share, creates an incorrect bookmark in macOS 26.1: let bookmark = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil) I have tested this on two different Macs with macOS 26.1 with two different Windows PC both hosting NTFS files shares via SMB. My questions: Have anyone else encountered this issue in macOS 26? Perhaps even with other fileshare types? Is there a workaround or some new project configuration needed in Xcode to get this working?
Replies
8
Boosts
0
Views
237
Activity
Nov ’25
Security-scoped bookmarks to external volumes are resolved to /
Users of my different apps started reporting an issue that could be related to the ones discussed in this other post: paths on an external volume, such as one mounted by "NTFS for Mac", or a path on a Synology volume, are "converted" to / (Macintosh HD) after going through "laundry" (creating the security-scoped bookmark, resolving the URL from it and using this new URL instead of the one returned by the open panel). Because of this issue, users of my apps are unable to select external volumes, which renders the different apps more or less useless. I've already received many emails regarding this issue in the past few days. A timely fix or suggestion for a workaround would be much appreciated, so that they don't have to wait for months before the next minor macOS release. The intention of this post is also to show users of my apps that this is a real issue. I created FB21002290 and TSI 16931637.
Replies
1
Boosts
0
Views
197
Activity
Nov ’25
How to check if a sandboxed app already has the access permission to a URL
I want to check whether a sandboxed application already has access permission to a specific URL. Based on my investigation, the following FileManager method seems to be able to determine it: FileManager.default.isReadableFile(atPath: fileURL.path) However, the method name and description don't explicitly mention this use case, so I'm not confident there aren't any oversights. Also, since this method takes a String path rather than a URL, I'd like to know if there's a more modern API available. I want to use this information to decide whether to prompt the user about the Sandbox restriction in my AppKit-based app.
Replies
5
Boosts
0
Views
536
Activity
Nov ’25
Exact meaning of NSURLBookmarkCreationMinimalBookmark
For bookmark creation and resolving, there's a NSURLBookmark{Creation,Resolution}MinimalBookmark enum value. What does this value imply on macOS and iOS? Specifically, to create security scoped bookmarks on macOS, we use NSURLBookmarkResolutionWithSecurityScope, but that is not available on iOS. Are iOS bookmarks always security scoped? Does the minimal enum imply security scoped bookmarks? Is 0 a valid value to bookmarkDataWithOptions, and does that give an even less scoped bookmark than NSURLBookmarkCreationMinimalBookmark`? We are also using NSURLBookmarkCreationWithoutImplicitSecurityScope on both iOS and macOS, to avoid any implicit resolution of bookmarks we resolve, so that we can explicitly control access by explicit calls to start/stopAccessing. How does NSURLBookmarkCreationWithoutImplicitSecurityScope relate to the enum values discussed above? Thanks! (https://mothersruin.com/software/Archaeology/reverse/bookmarks.html provides some really interesting insights, but doesn't discuss the minimal bookmarks.)
Replies
5
Boosts
1
Views
176
Activity
Nov ’25
macOS 26.1 – Severe lag in Open/Save panels when iCloud Drive root contains any items (FileProvider v3 regression)
I’ve filed this as FB20943098 (macOS 26.1 – FileProvider v3 synchronous enumeration bug), but posting here in case others can reproduce and add duplicates. Systems: macOS 26.1 (26B82) M4 Mac mini Pro and M4 MacBook Air Symptoms: In any app (TextEdit, Pages, Browsers, etc.), the Open/Save dialog lags for ~1s per folder navigation click. CPU spikes from fileproviderd, cloudd, bird, and siriactionsd. Key discovery: If my iCloud Drive root is empty (only “Documents” and “Downloads”), performance is perfect. As soon as any folder or file exists at the root of iCloud Drive, the lag returns immediately. Moving those items into “Documents” or “Downloads” makes everything smooth again. Analysis: Based on process traces and container paths, this appears to originate in the FileProvider.framework subsystem (via fileproviderd), which mediates iCloud Drive. Early evidence suggests that folder enumeration of the iCloud Drive container root may be blocking UI threads in macOS 26.1. I believe this may be related to the recent internal migration of the file-provider backend (often referred to as “v3”), but I do not have direct confirmation from Apple of that exact change. MacOS 26.1’s new FileProvider v3 backend seems to be blocking the Open/Save panel while enumerating the iCloud Drive root container (~/Library/Application Support/FileProvider/723EBBFF-…). Folder enumeration seems to wait synchronously for metadata from fileproviderd, and if the local SQLite DB is busy (WAL writes or sync state checks), UI freezes briefly. Workarounds: Disabling iCloud Drive entirely fixes the issue. Simply disabling Desktop/Documents sync does not help. Keeping the iCloud Drive root empty avoids the lag without turning iCloud off. I am able to store whatever I please in the Desktop or Documents folder which is currently syncing. Would appreciate if others on 26.1 could confirm. Engineers: I’ve attached fs_usage, log stream, and process samples to my Feedback ticket via the FB20943098. Expected behavior: Folder enumeration in NSOpenPanel should remain asynchronous regardless of FileProvider background activity. Open/save modal should be responsive and smooth.
Replies
6
Boosts
1
Views
1.7k
Activity
Nov ’25
Failed on creating static code object with API SecStaticCodeCreateWithPath(_:_:_:)
My process running with root privilege, but got below error with API SecStaticCodeCreateWithPath(::_:) to create static code object for Cortex XDR Agent app, it working fine for other app like Safari on same device. 2025-07-22 02:02:05.857719(-0600)[23221:520725] DBG Found /Library/Application Support/PaloAltoNetworks/Traps/bin/Cortex XDR Agent.app,/Library/Application Support/PaloAltoNetworks/Traps/bin/Cortex XDR Agent.app running. Will verify the process now 2025-07-22 02:02:05.859209(-0600)[23221:520725] ERR Failed to create static code for path /Library/Application Support/PaloAltoNetworks/Traps/bin/Cortex XDR Agent.app/Contents/MacOS/Cortex XDR Agent. Error: Optional(UNIX[Operation not permitted]) Code Snippet let fileURL = URL(fileURLWithPath: processPath) var code: SecStaticCode? let rc = SecStaticCodeCreateWithPath(fileURL as CFURL, [], &code) if rc == errSecSuccess, let code = code { staticCode = code } else { ZSLoggerError("Failed to create static code for path \(processPath). Error: \(String(describing: SecCopyErrorMessageString(rc, nil)))") return nil }
Replies
3
Boosts
0
Views
151
Activity
Nov ’25
`NewDocumentButton(contentType:)` gives "Content serialization failed, document won't be saved."
I'm working on an iOS document-based app. It uses ReferenceFileDocument and custom creation of documents via DocumentGroupLaunchScene + NewDocumentButton. It works fine when I use the plain NewDocumentButton("Whatever") (without any more arguments), but when I want to perform additional setup via preapreDocumentURL or even just add a contentType it gives such output in the console when I hit it: Content serialization failed, document won't be saved. UTType.replayable is correctly wired up in the plist. It looks like a bug in the SDK, but maybe there is a chance that I'm doing something wrong? Here's a code: import SwiftUI import UniformTypeIdentifiers import Combine @main struct MyApp: App { var body: some Scene { DocumentGroup { Document() } editor: { documentConfiguration in EmptyView() } DocumentGroupLaunchScene("Yoyo") { NewDocumentButton(contentType: .replayable) { return URL(string: "whatever, it doesnt even go there...")! } } } } final class Document: ReferenceFileDocument { static var readableContentTypes: [UTType] { [.replayable] } @Published var x = 0 init() {} init(configuration: ReadConfiguration) throws {} func snapshot(contentType: UTType) throws -> Data { Data() } func fileWrapper(snapshot: Data, configuration: WriteConfiguration) throws -> FileWrapper { .init(regularFileWithContents: snapshot) } } extension UTType { static var replayable: UTType { UTType(exportedAs: "com.whatever.yo") } }
Replies
2
Boosts
0
Views
199
Activity
Nov ’25
How to detect an auto-mounting directory and wait for it to get mounted?
I need to detect the triggering of an auto-mount operation when accessing the path to a formerly unknown mount point at the file system (BSD, POSIX, NSURL) level, and how to wait for it to finish the operation. Network shares can have sub-volumes on them Consider a Windows server. Let's say there's a SMB sharepoint at C:\Shared. It has some folders, one of which is at C:\Shared\More. Furthermore, there's another partition (volume) on the PC, which is mounted at C:\Shared\More\OtherVol. If you mount the initial share on a Mac with a recent macOS, macOS initially only sees a single mount point at /Volumes/Shared, which can be checked with the "mount" command. Now, if you use Finder to dive into the Shared/More folder, Finder will trigger an auto-mount action on the containing OtherVol folder, and after that, the "mount" command will list two mount points from this server, the second being at /Volumes/Shared/More/OtherVol. (This was a bit surprising to me - I'd have thought that Windows or SMB would hide the fact that the share has sub-volumes, and simply show them as directories - and that's what it did in older macOS versions indeed, e.g. in High Sierra. But in Sequoia, these sub-volumes on the Windows side are mirrored on the Mac side, and they behave accordingly) Browse the volume, including its sub-volumes Now, I have a program that tries to dive into all the folders of this Shared volume, even if it was just freshly mounted and there's no mountpoint at /Volumes/Shared/More/OtherVol known yet (i.e. the user didn't use Finder to explore it). This means, that if my program, e.g. using a simple recursive directory scan, reaches /Volumes/Shared/More/OtherVol, the item will not appear as a volume but as an empty folder. E.g, if I get the NSURLIsVolumeKey value, it'll be false. Only once I try to enter the empty dir, listing its contents, which will return no items, an auto-mount action will get triggered, which will add the mountpoint at the path. So, in order to browse the actual contents of the OtherVol directory, I'd have to detect this auto-mount operation somehow, wait for it to finish mounting, and then re-enter the same directory so that I now see the mounted content. How do I do that? I.e. how do I tell that a dir is actually a auto-mount point and how do I wait for it to get auto-mounted before I continue to browse its contents? Note that newer macOS versions do not use fstab any more, so that's of no help here. Can the DA API help? Do I need to use the old Disk Arbitration functions for this, somehow? I have used the DA framework in the part to prevent auto-mounting, so I imagine I could hook into that handler, and if I get a callback for a mount operation, I could then queue the newly mounted volume for scanning. The problem, however, is that my scanning code may, having only seen an empty directory at the not-yet-mounted mountpoint, already decided that there's nothing there and finished its operation. I'd need some reliable method that lets my recursive scanning code know whether an auto-mount has been triggered and it therefore needs to wait for the DA callback. So, is there some signal that will let me know IMMEDIATELY after entering the empty mountpoint directory that an auto-mount op is on the way? Because I suspect that the DA callbacks come with a delay, and therefore would come too late if I used that as the notifier that I have to wait.
Replies
11
Boosts
0
Views
699
Activity
Nov ’25
Trying to remove app groups from my macOS app doesn't seem to work
Hi, a short question really, which boils down to... How do I make sure I have removed all usage of app groups in my Mac app store app, such that the Mac app store agrees I have! Fundamentally, what I'm trying to do is transfer my app to another developer. In previous releases of this app on the App Store, I used a shared app group container to communicate between the main app and it's (embedded) XPC service, but this blocks App Store transfer of the app to another developer. So I came up with another approach for the App and XPC service to communicate (using a URL bookmark for security scoped files to be passed to the XPC service). And then tried various things to get the app store to accept that I'm no longer using app groups. So far with no luck... removed the app groups entitlements by hand from the entitlements files used to sign the main app and the XPC service, respectively. when that didn't work, go into the Developer Portal, find the app ids for the main app and the XPC service, make sure those app ids had the app groups entitlement removed too, created a new provisioning profile for the app, based on this updated app id, downloaded it, rebuilt an app archive using this updated provisioning profile and used it to create another new release on the app store when that didn't work, found and deleted all app app groups in my developer account in the developer portal itself None of the above worked. When I try to transfer the app in App Store Connect, I still see the same message, "You can't transfer this app because of the following reasons: Sandboxed Group Container You can only transfer sandboxed apps that are not sharing a group container." I'm now pretty far from using a shared group container, so I'm puzzled why it still thinks I am? There is one last thing I can try... I noticed over the weekend that even though the entitlement is gone, there's one place in code that may or may not be run on rare occasions (hard to tell) that attempts to open the app group shared container with the code... let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: ...which I think is just returning nil and doing nothing. Potentially the App Store sees that attempted API access for shared group containers and assumes I'm still using app groups (even though there's no entitlement so that call will always be failing)? I can do yet another App Store update and just remove that code. But I want to get to the bottom of why it has been failing all this time. What is App Store Connect / the Mac App Store looking at that makes it think I'm still using app groups? I've tried so many things and don't want to mess users around with another App Store update unless this code above is the actual cause! Cheers p.s. It's a teamID based app group of the form... MY_TEAM_ID.s4a e.g. SWDC5K54B7.s4a
Replies
4
Boosts
0
Views
288
Activity
Nov ’25
FileProviderUI prepare method receives internal fileprovider ID list instead of actual itemIdentifier
In the context of a FPUIActionExtensionViewController module the prepare method is defined like this: override func prepare(forAction actionIdentifier: String, itemIdentifiers: [NSFileProviderItemIdentifier]) { So you would expect the itemIdentifiers list to be the item identifier but instead it is a list of the internal fileprovider IDs like: __fp/fs/docID(6595461) So this is a bit problematic because the only way to recover the ID is by using getUserVisibleURL to get the path which is not great. Is there a better way ? Am I missing something ? Thanks,
Replies
5
Boosts
0
Views
364
Activity
Nov ’25
Opening two (or more files) with one dialog box (save panel)
I am slowly converting an Objective C with C program to Swift with C. All of my menus and dialog boxes are now in Swift, but files are still opened and closed in Objective C and C. The following code is Objective C and tries to open two files in the same directory with two related names after getting the base of the name from a Save Panel. The code you see was modified by ChatGPT 5.0, and similar code was modified by Claude. Both LLMs wrote code that failed because neither knows how to navigate Apple’s sandbox. Does anybody understand Apple’s sandbox? I eventually want to open more related files and do not want the user to have to click through multiple file dialog boxes. What is the best solution? Are the LLMs just not up to the task and there is a simple solution to the Objective C code? Is this easier in Swift? Other ideas? Thanks in advance for any help. (BOOL)setupOutputFilesWithBaseName:(NSString*)baseName { NSString *outFileNameStr = baseName; if (outFileNameStr == nil || [outFileNameStr length] == 0) { outFileNameStr = @"output"; } // Show ONE save panel for the base filename NSSavePanel *savePanel = [NSSavePanel savePanel]; [savePanel setMessage:@"Choose base name and location for output files\n(Two files will be created: one ending with 'Pkout', one with 'Freqout')"]; [savePanel setNameFieldStringValue:outFileNameStr]; if (directoryURL != nil) { [savePanel setDirectoryURL:directoryURL]; } if ([savePanel runModal] != NSModalResponseOK) { NSLog(@"User cancelled file selection"); return NO; } // Get the selected file URL - this gives us security access to the directory NSURL *baseFileURL = [savePanel URL]; // Get the directory - THIS is what we need for security scope NSURL *dirURL = [baseFileURL URLByDeletingLastPathComponent]; // Start accessing the DIRECTORY, not just the file BOOL didStartAccessing = [dirURL startAccessingSecurityScopedResource]; if (!didStartAccessing) { NSLog(@"Warning: Could not start security-scoped access to directory"); } NSString *baseFileName = [[baseFileURL lastPathComponent] stringByDeletingPathExtension]; NSString *extension = [baseFileURL pathExtension]; // Create the two file names with suffixes NSString *pkoutName = [baseFileName stringByAppendingString:@"Pkout"]; NSString *freqoutName = [baseFileName stringByAppendingString:@"Freqout"]; NSURL *pkoutURL = [dirURL URLByAppendingPathComponent:pkoutName]; NSURL *freqoutURL = [dirURL URLByAppendingPathComponent:freqoutName]; NSLog(@"Attempting to open: %@", [pkoutURL path]); NSLog(@"Attempting to open: %@", [freqoutURL path]); // Open the first file (Pkout) globalFpout = fopen([[pkoutURL path] UTF8String], "w+"); if (globalFpout == NULL) { int errnum = errno; NSLog(@"Error: Could not open Pkout file at %@", [pkoutURL path]); NSLog(@"Error code: %d - %s", errnum, strerror(errnum)); if (didStartAccessing) { [dirURL stopAccessingSecurityScopedResource]; } return NO; } NSLog(@":white_check_mark: Pkout file opened: %@", [pkoutURL path]); // Open the second file (Freqout) globalFpfrqout = fopen([[freqoutURL path] UTF8String], "w+"); if (globalFpfrqout == NULL) { int errnum = errno; NSLog(@"Error: Could not open Freqout file at %@", [freqoutURL path]); NSLog(@"Error code: %d - %s", errnum, strerror(errnum)); fclose(globalFpout); globalFpout = NULL; if (didStartAccessing) { [dirURL stopAccessingSecurityScopedResource]; } return NO; } NSLog(@":white_check_mark: Freqout file opened: %@", [freqoutURL path]); // Store the directory URL so we can stop accessing later secureDirectoryURL = dirURL; return YES; }
Replies
0
Boosts
0
Views
426
Activity
Nov ’25
hdiutil prints invisible characters for its devnode output
This script from man hdiutil no longer works: devnode=$(hdiutil attach -nomount ram://102400) newfs_hfs “$devnode” mount -t hfs “$devnode” /path/to/ramdisk because $devnode contains spaces and tabs!! $ hdiutil attach -nomount ram://1 | xxd 00000000: 2f64 6576 2f64 6973 6b34 2020 2020 2020 /dev/disk4 00000010: 2020 2020 0920 2020 2020 2020 2020 2020 . 00000020: 2020 2020 2020 2020 2020 2020 2020 2020 00000030: 2020 2020 090a # remember to clean up afterwards $ hdiutil detach /dev/disk4 Please properly quote your variables in CI test scripts to catch such regression. It could pass because unquoted expansion of $devnode undergoes word splitting after the variable is substituted, removing the trailing whitespaces. FB20303191
Replies
1
Boosts
0
Views
97
Activity
Nov ’25
BUG: iOS 18 Simulator cannot "Save to Files"
On iOS 18.0+ simulators, tap any share link button from any app, select "Save to Files", the "Save" button is disabled. In all previous simulator versions this works. This behavior even happens with default Apple apps like Photos. Simulator: Version 16.0 (1037) XCode: Version 16.1 beta (16B5001e) macOS: 14.6.1 (23G93)
Replies
11
Boosts
8
Views
2.3k
Activity
Nov ’25
On File System Permissions
Modern versions of macOS use a file system permission model that’s far more complex than the traditional BSD rwx model, and this post is my attempt at explaining that model. If you have a question about this, post it here on DevForums. Put your thread in the App & System Services > Core OS topic area and tag it with Files and Storage. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" On File System Permissions Modern versions of macOS have five different file system permission mechanisms: Traditional BSD permissions Access control lists (ACLs) App Sandbox Mandatory access control (MAC) Endpoint Security (ES) The first two were introduced a long time ago and rarely trip folks up. The second two are newer, more complex, and specific to macOS, and thus are the source of some confusion. Finally, Endpoint Security allows third-party developers to deny file system operations based on their own criteria. This post offers explanations and advice about all of these mechanisms. Error Codes App Sandbox and the mandatory access control system are both implemented using macOS’s sandboxing infrastructure. When a file system operation fails, check the error to see whether it was blocked by this sandboxing infrastructure. If an operation was blocked by BSD permissions or ACLs, it fails with EACCES (Permission denied, 13). If it was blocked by something else, it’ll fail with EPERM (Operation not permitted, 1). If you’re using Foundation’s FileManager, these error are both reported as Foundation errors, for example, the NSFileReadNoPermissionError error. To recover the underlying error, get the NSUnderlyingErrorKey property from the info dictionary. App Sandbox File system access within the App Sandbox is controlled by two factors. The first is the entitlements on the main executable. There are three relevant groups of entitlements: The com.apple.security.app-sandbox entitlement enables the App Sandbox. This denies access to all file system locations except those on a built-in allowlist (things like /System) or within the app’s containers. The various “standard location” entitlements extend the sandbox to include their corresponding locations. The various “file access temporary exceptions” entitlements extend the sandbox to include the items listed in the entitlement. Collectively this is known as your static sandbox. The second factor is dynamic sandbox extensions. The system issues these extensions to your sandbox based on user behaviour. For example, if the user selects a file in the open panel, the system issues a sandbox extension to your process so that it can access that file. The type of extension is determined by the main executable’s entitlements: com.apple.security.files.user-selected.read-only results in an extension that grants read-only access. com.apple.security.files.user-selected.read-write results in an extension that grants read/write access. Note There’s currently no way to get a dynamic sandbox extension that grants executable access. For all the gory details, see this post. These dynamic sandbox extensions are tied to your process; they go away when your process terminates. To maintain persistent access to an item, use a security-scoped bookmark. See Accessing files from the macOS App Sandbox. To pass access between processes, use an implicit security scoped bookmark, that is, a bookmark that was created without an explicit security scope (no .withSecurityScope flag) and without disabling the implicit security scope (no .withoutImplicitSecurityScope flag)). If you have access to a directory — regardless of whether that’s via an entitlement or a dynamic sandbox extension — then, in general, you have access to all items in the hierarchy rooted at that directory. This does not overrule the MAC protection discussed below. For example, if the user grants you access to ~/Library, that does not give you access to ~/Library/Mail because the latter is protected by MAC. Finally, the discussion above is focused on a new sandbox, the thing you get when you launch a sandboxed app from the Finder. If a sandboxed process starts a child process, that child process inherits its sandbox from its parent. For information on what happens in that case, see the Note box in Enabling App Sandbox Inheritance. IMPORTANT The child process inherits its parent process’s sandbox regardless of whether it has the com.apple.security.inherit entitlement. That entitlement exists primarily to act as a marker for App Review. App Review requires that all main executables have the com.apple.security.app-sandbox entitlement, and that entitlements starts a new sandbox by default. Thus, any helper tool inside your app needs the com.apple.security.inherit entitlement to trigger inheritance. However, if you’re not shipping on the Mac App Store you can leave off both of these entitlement and the helper process will inherit its parent’s sandbox just fine. The same applies if you run a built-in executable, like /bin/sh, as a child process. When the App Sandbox blocks something, it might generates a sandbox violation report. For information on how to view these reports, see Discovering and diagnosing App Sandbox violations. To learn more about the App Sandbox, see the various links in App Sandbox Resources. For information about how to embed a helper tool in a sandboxed app, see Embedding a Command-Line Tool in a Sandboxed App. Mandatory Access Control Mandatory access control (MAC) has been a feature of macOS for many releases, but it’s become a lot more prominent since macOS 10.14. There are many flavours of MAC but the ones you’re most likely to encounter are: Full Disk Access (macOS 10.14 and later) Files and Folders (macOS 10.15 and later) App bundle protection (macOS 13 and later) App container protection (macOS 14 and later) App group container protection (macOS 15 and later) Data Vaults (see below) and other internal techniques used by various macOS subsystems Mandatory access control, as the name suggests, is mandatory; it’s not an opt-in like the App Sandbox. Rather, all processes on the system, including those running as root, as subject to MAC. Data Vaults are not a third-party developer opportunity. See this post if you’re curious. In the Full Disk Access and Files and Folders cases, users grant a program a MAC privilege using System Settings > Privacy & Security. Some MAC privileges are per user (Files and Folders) and some are system wide (Full Disk Access). If you’re not sure, run this simple test: On a Mac with two users, log in as user A and enable the MAC privilege for a program. Now log in as user B. Does the program have the privilege? If a process tries to access an item restricted by MAC, the system may prompt the user to grant it access there and then. For example, if an app tries to access the desktop, you’ll see an alert like this: “AAA” would like to access files in your Desktop folder. [Don’t Allow] [OK] To customise this message, set Files and Folders properties in your Info.plist. This system only displays this alert once. It remembers the user’s initial choice and returns the same result thereafter. This relies on your code having a stable code signing identity. If your code is unsigned, or signed ad hoc (Signed to Run Locally in Xcode parlance), the system can’t tell that version N+1 of your code is the same as version N, and thus you’ll encounter excessive prompts. Note For information about how that works, see TN3127 Inside Code Signing: Requirements. The Files and Folders prompts only show up if the process is running in a GUI login session. If not, the operation is allowed or denied based on existing information. If there’s no existing information, the operation is denied by default. For more information about app and app group container protection, see the links in Trusted Execution Resources. For more information about app groups in general, see App Groups: macOS vs iOS: Working Towards Harmony On managed systems the site admin can use the com.apple.TCC.configuration-profile-policy payload to assign MAC privileges. For testing purposes you can reset parts of TCC using the tccutil command-line tool. For general information about that tool, see its man page. For a list of TCC service names, see the posts on this thread. Note TCC stands for transparency, consent, and control. It’s the subsystem within macOS that manages most of the privileges visible in System Settings > Privacy & Security. TCC has no API surface, but you see its name in various places, including the above-mentioned configuration profile payload and command-line tool, and the name of its accompanying daemon, tccd. While tccutil is an easy way to do basic TCC testing, the most reliable way to test TCC is in a VM, restoring to a fresh snapshot between each test. If you want to try this out, crib ideas from Testing a Notarised Product. The MAC privilege mechanism is heavily dependent on the concept of responsible code. For example, if an app contains a helper tool and the helper tool triggers a MAC prompt, we want: The app’s name and usage description to appear in the alert. The user’s decision to be recorded for the whole app, not that specific helper tool. That decision to show up in System Settings under the app’s name. For this to work the system must be able to tell that the app is the responsible code for the helper tool. The system has various heuristics to determine this and it works reasonably well in most cases. However, it’s possible to break this link. I haven’t fully research this but my experience is that this most often breaks when the child process does something ‘odd’ to break the link, such as trying to daemonise itself. If you’re building a launchd daemon or agent and you find that it’s not correctly attributed to your app, add the AssociatedBundleIdentifiers property to your launchd property list. See the launchd.plist man page for the details. Scripting MAC presents some serious challenges for scripting because scripts are run by interpreters and the system can’t distinguish file system operations done by the interpreter from those done by the script. For example, if you have a script that needs to manipulate files on your desktop, you wouldn’t want to give the interpreter that privilege because then any script could do that. The easiest solution to this problem is to package your script as a standalone program that MAC can use for its tracking. This may be easy or hard depending on the specific scripting environment. For example, AppleScript makes it easy to export a script as a signed app, but that’s not true for shell scripts. TCC and Main Executables TCC expects its bundled clients — apps, app extensions, and so on — to use a native main executable. That is, it expects the CFBundleExecutable property to be the name of a Mach-O executable. If your product uses a script as its main executable, you’re likely to encounter TCC problems. To resolve these, switch to using a Mach-O executable. For an example of how you might do that, see this post. Endpoint Security Endpoint Security (ES) is a general mechanism for third-party products to enforce custom security policies on the Mac. An ES client asks ES to send it events when specific security-relevant operations occur. These events can be notifications or authorisations. In the case of authorisation events, the ES client must either allow or deny the operation. As you might imagine, the set of security-relevant operations includes file system operations. For example, when you open a file using the open system call, ES delivers the ES_EVENT_TYPE_AUTH_OPEN event to any interested ES clients. If one of those ES client denies the operation, the open system call fails with EPERM. For more information about ES, see the Endpoint Security framework documentation. Revision History 2025-11-04 Added a discussion of Endpoint Security. Made numerous minor editorial changes. 2024-11-08 Added info about app group container protection. Clarified that Data Vaults are just one example of the techniques used internally by macOS. Made other editorial changes. 2023-06-13 Replaced two obsolete links with links to shiny new official documentation: Accessing files from the macOS App Sandbox and Discovering and diagnosing App Sandbox violations. Added a short discussion of app container protection and a link to WWDC 2023 Session 10053 What’s new in privacy. 2023-04-07 Added a link to my post about executable permissions. Fixed a broken link. 2023-02-10 In TCC and Main Executables, added a link to my native trampoline code. Introduced the concept of an implicit security scoped bookmark. Introduced AssociatedBundleIdentifiers. Made other minor editorial changes. 2022-04-26 Added an explanation of the TCC initialism. Added a link to Viewing Sandbox Violation Reports.  Added the TCC and Main Executables section. Made significant editorial changes. 2022-01-10 Added a discussion of the file system hierarchy. 2021-04-26 First posted.
Replies
0
Boosts
0
Views
12k
Activity
Nov ’25
Drag and Drop stopped working after upgrading from macOS 15 to 26
When I drag and drop a file with flag "shouldAttemptToOpenInPlace: true", I was able to access the original file name in macOS 15. After upgrading to macOS 26, I can't access the original file name anymore. Instead, I got some useless file name such as ".com.apple.Foundation.NSItemProvider.gKZ91u.tmp". The app no longer works with these tmp filenames because it needs the orignal file name to do the file transfer. (Btw, this is a WinSCP like app on Mac platform) Could you please check and fix this issue? Thank you. FileRepresentation(contentType: .item, shouldAttemptToOpenInPlace: true)
Replies
1
Boosts
0
Views
404
Activity
Nov ’25