Supported read/write handoff of a sandbox-container PNG to Preview using NSWorkspace

Hello,

I am preparing an existing macOS screenshot utility for distribution through the Mac App Store.

The app stores captured PNG files under its temporary directory:

FileManager.default.temporaryDirectory .appendingPathComponent("ShelfDragPoC/Captures", isDirectory: true)

A context-menu "Edit" action passes the original PNG URL to Preview using NSWorkspace. The app does not create an editing copy.

Relevant code:

import AppKit

@MainActor func openInPreview(_ url: URL) { guard let previewURL = NSWorkspace.shared.urlForApplication( withBundleIdentifier: "com.apple.Preview" ) else { return }

let configuration = NSWorkspace.OpenConfiguration()
configuration.activates = true

NSWorkspace.shared.open(
    [url],
    withApplicationAt: previewURL,
    configuration: configuration
) { _, _ in }

}

The app monitors the original PNG URL for file changes and refreshes its thumbnail when changes are detected.

Observed behavior:

  1. In the existing non-sandboxed app, rotating an image in Preview updates the original PNG and the thumbnail without requiring Command-S.

  2. In the sandboxed validation app, Preview opens the image, but editing results in a separate copy.

  3. When closing the edited document, Preview displays a message indicating that the original document will not be changed.

  4. The original PNG and the app's thumbnail are not updated.

The Preview launch code and file watcher are unchanged between the non-sandboxed and sandboxed versions.

The sandboxed app has these entitlements:

  • com.apple.security.app-sandbox
  • com.apple.security.files.user-selected.read-write
  • com.apple.security.files.bookmarks.app-scope

The app-scoped bookmark is used for a separate Desktop export feature. The PNG opened in Preview remains in the app's sandbox container.

My question:

Is there a supported public API that allows a sandboxed Mac App Store app to open its own container-resident PNG in Preview with the permissions required for in-place editing and normal automatic saving?

Ideally, the user would only need to select "Edit" once, without an additional file-selection dialog or an explicit Save command.

We want to preserve the original PNG URL, keep App Sandbox enabled, and avoid automatically exporting temporary images to the Desktop.

If this workflow is not supported, what is Apple's recommended approach?

Thank you.

It's always risky trying to integrate with Apple's own apps.

Plus, in this modern age of paranoia, security restrictions may impact Apple apps as well as 3rd party apps. This file is in your app's container. I don't think what you're trying to accomplish is documented in any way. The only documentation and API support is to prevent the action you describe.

I think there are multiple other APIs to get data (or "document data") from one app to another. But then monitoring the other side is, at best, risky, and often flat-out impossible. The user can always rename or save elsewhere. If your app is claiming it can monitor that activity, the user is going to blame your app when it fails.

Then there's a more existential issue. You're essentially unhorsing yourself. You want users to use your app. The last thing you should ever do it launch someone else's app, even Apple's. It's your app. That's your user. Keep them in your app. Maybe you can use PDFKit and do those same operations totally inside your app.

This is going to be tricky. There are multiple potentially conflict file system permissions constraints in play here. I talk about those in On File System Permissions.

I’d like to clarify this bit of your question:

Written by SuzuyaKoboDev in 852014021

The app stores captured PNG files under its temporary directory:

Are you talking about the actual temporary directory, as returned by the temporaryDirectory property, or the older NSTemporaryDirectory()? Or a directory you manage that just happens to contain files that you consider temporary?

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi Quinn,

Thank you for looking into this.

It is A: FileManager.default.temporaryDirectory.

The app creates a subdirectory beneath the URL returned by that API:

FileManager.default.temporaryDirectory
    .appendingPathComponent("ShelfDragPoC/Captures", isDirectory: true)

The captured image is saved as a PNG using Data.write(to:options: .atomic), and the resulting URL is passed to Preview via NSWorkspace.open(_:withApplicationAt:configuration:completionHandler:).

The minimal reproduction project uses the same API and write method, with a different subdirectory (PreviewSandboxRepro/Captures) and a synthetic PNG.

Neither implementation explicitly calls NSTemporaryDirectory() or uses a separately chosen temporary-directory root.

Thank you!