For new macOS apps, use Apple’s ScreenCaptureKit: request shareable content, select an SCWindow or SCDisplay, create an SCContentFilter, and capture one image with the screenshot API available in your target SDK. Use an SCStream instead when you need a recording or a sequence of frames. The older Core Graphics CGWindowListCreateImage function is deprecated.
Choose a still image or a stream first
The implementation depends on whether you need one frame or continuous output. ScreenCaptureKit provides both controlled source selection and capture configuration.
| Need | Use | What you control |
|---|---|---|
| One PNG, JPEG, or other image | The screenshot interface exposed by your target SDK, using SCScreenshotManager and SCScreenshotConfiguration |
Window or display, output width and height, image quality, and filtering |
| Recording, streaming, OCR, computer vision, or many frames | SCStream with a stream configuration and output delegate |
Frame cadence, dimensions, pixel format, audio scope, and ongoing processing |
Also decide whether the source is one window, one display, or several displays; whether the app should choose silently or let the person choose; and which macOS deployment target your app supports. Apple’s update history records screenshot support with SCStream in June 2023 and screenshots across multiple displays in June 2024. Check the SDK documentation for the exact availability annotation and Swift signature of the screenshot method you select.
Prepare the macOS project and permission flow
Add ScreenCaptureKit
Import ScreenCaptureKit in the target and link the framework in Xcode. The code below assumes an SDK that exposes SCScreenshotManager.captureImage(contentFilter:configuration:). If that symbol is unavailable for your deployment target, use the stream/frame route described later or raise the target after confirming the supported OS version.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →#1 Best Overall
- BRILLLLLLIANT — iMac is the ultimate all-in-one desktop computer, powered by the M4 chip and built for Apple Intelligence.* With a stunning 24-inch Retina display, iMac gives you the space you need in an iconic, colorful design that livens up any room.
- FITS PERFECTLY IN YOUR SPACE — The all-in-one desktop design is strikingly thin, comes in seven vibrant colors, and elevates any space with style.
- BUILT FOR APPLE INTELLIGENCE — Apple Intelligence is the personal intelligence system that helps you write, express yourself, and get things done effortlessly. With groundbreaking privacy protections, it gives you peace of mind that no one else can access your data — not even Apple.*
- SUPERCHARGED BY M4 — Get more done faster with the Apple M4 chip. From editing photos to creating presentations to gaming, you’ll fly through work and play.
- IMMERSIVE DISPLAY — The industry-leading 24-inch 4.5K Retina display features 500 nits of brightness and supports up to 1 billion colors.*
Explain the request in Info.plist
Add the NSScreenCaptureUsageDescription key in the app target’s Info pane. Give a plain-language reason, such as “This app captures the window you choose to create a support image.” Apple instructs developers to request screen-recording permission before capturing content.
Screen recording authorization is separate from camera and microphone authorization. Do not add NSCameraUsageDescription or NSMicrophoneUsageDescription unless the app also captures those devices.
Expect a user decision
On first use, macOS can show the Screen Recording permission prompt. The ScreenCaptureKit sample from Apple requires a restart after permission is granted; treat that as sample-specific guidance and design your own app to re-check authorization when it returns to the foreground. A denied, revoked, or not-yet-effective permission must produce an actionable message rather than an empty image.
Complete Swift example: capture a named window as PNG
This command-line example enumerates on-screen content, finds a window by title, captures it, and writes a PNG. It uses the current screenshot API when that API is present in the target SDK. Window titles are not guaranteed to be unique, so production code should add stronger selection rules where possible.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallimport Foundation
import AppKit
import CoreGraphics
import ImageIO
import ScreenCaptureKit
import UniformTypeIdentifiers
enum CaptureError: LocalizedError {
case permissionDenied
case windowNotFound(String)
case couldNotCreateDestination
case couldNotWriteImage
var errorDescription: String? {
switch self {
case .permissionDenied:
return "Screen Recording permission is not available. Enable it in System Settings, then relaunch the app."
case .windowNotFound(let title):
return "No on-screen window matched: (title)"
case .couldNotCreateDestination:
return "The PNG destination could not be created."
case .couldNotWriteImage:
return "The PNG could not be finalized."
}
}
}
@available(macOS 14.0, *)
func captureWindow(titled title: String, outputURL: URL) async throws {
// This check avoids a confusing empty-content result.
guard CGPreflightScreenCaptureAccess() else {
_ = CGRequestScreenCaptureAccess()
throw CaptureError.permissionDenied
}
let content = try await SCShareableContent.excludingDesktopWindows(
false,
onScreenWindowsOnly: true
)
guard let window = content.windows.first(where: { $0.title == title }) else {
throw CaptureError.windowNotFound(title)
}
let filter = SCContentFilter(desktopIndependentWindow: window)
let configuration = SCScreenshotConfiguration()
// Confirm the exact availability and configuration properties in the SDK
// selected by your project before setting width, height, or image quality.
let image = try await SCScreenshotManager.captureImage(
contentFilter: filter,
configuration: configuration
)
guard let destination = CGImageDestinationCreateWithURL(
outputURL as CFURL,
UTType.png.identifier as CFString,
1,
nil
) else {
throw CaptureError.couldNotCreateDestination
}
CGImageDestinationAddImage(destination, image, nil)
guard CGImageDestinationFinalize(destination) else {
throw CaptureError.couldNotWriteImage
}
}
@main
struct ScreenshotCLI {
static func main() async {
do {
let output = URL(fileURLWithPath: "/tmp/window-shot.png")
try await captureWindow(titled: "Safari", outputURL: output)
print("Saved (output.path)")
} catch {
fputs("Capture failed: (error.localizedDescription)n", stderr)
exit(EXIT_FAILURE)
}
}
}
Build this as a macOS command-line tool or adapt captureWindow to an AppKit or SwiftUI action. Replace “Safari” with the exact visible title. The first call can return no usable content when permission has just changed; relaunching after approval is a safe recovery path.
Capture a full display instead of one window
Use the same enumeration step, select an SCDisplay, and create a display filter. The relevant selection pattern is:
guard let display = content.displays.first else {
throw CaptureError.windowNotFound("an available display")
}
let filter = SCContentFilter(display: display, excludingWindows: [])
let configuration = SCScreenshotConfiguration()
let image = try await SCScreenshotManager.captureImage(
contentFilter: filter,
configuration: configuration
)
For multiple monitors, choose the intended SCDisplay rather than assuming index zero. If your SDK supports multi-display screenshots, decide whether the result should be one combined image or one image per display and test coordinate and scaling behavior on the macOS versions you support.
Configure dimensions, quality, and excluded content
SCScreenshotConfiguration exposes output width, output height, and image-quality controls in SDKs that provide those properties. Set them only after checking the target SDK’s declarations. A Retina display can produce a larger pixel image than its point dimensions; choose an explicit output size when downstream systems have a fixed limit.
Free tools Windows power users keep installed
One-click scans. No signup required.
A content filter determines what is included. For a display capture, exclude windows that should not appear when your privacy requirements demand it. For a single-window capture, the window-specific filter avoids unrelated desktop content. Always test minimized, hidden, closed, or rapidly changing windows; a stored window object does not guarantee that the window will still be capturable later.
When a stream is the better API
Use SCStream when you need repeated frames, a recording, live preview, or frame-by-frame processing. Create the same kind of window or display SCContentFilter, configure an SCStreamConfiguration, register a stream-output handler, and start capture. Stop the stream promptly when the operation ends.
- Set width and height deliberately to avoid processing more pixels than your pipeline needs.
- Choose a frame interval and pixel format that your encoder or computer-vision code accepts.
- Handle dropped frames and back-pressure; a slow consumer should not block the capture thread.
- Keep audio disabled unless the product genuinely needs it and has the corresponding user experience.
For a person-driven sharing workflow, Apple recommends the system content-sharing picker so users can choose shareable content and manage active streams. A silent, app-directed one-shot screenshot is different: if the user has already selected the window in your UI, a picker may add unnecessary friction.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Permission, source, and lifecycle failure handling
Permission denied or revoked
Show the user that Screen Recording access is required and direct them to System Settings’ Privacy & Security section. Re-check authorization when the app becomes active. Do not substitute camera or microphone prompts; they do not grant desktop capture access.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #2
- Renewed products look and work like new. These pre-owned products have been inspected and tested by Amazon-qualified suppliers, which typically perform a full diagnostic test, replacement of any defective parts, and a thorough cleaning process. Packaging and accessories may be generic. All products on Amazon Renewed come with a minimum 90-day supplier-backed warranty.
No windows or displays returned
Content can be empty when permission is missing, the desktop is locked, or the requested source is no longer on screen. Treat an empty list as a recoverable state: explain it, refresh the enumeration, and let the user choose again.
The title lookup fails
Titles can change, be localized, or collide across windows. Match the owning application, inspect the available SCWindow objects, and let the user select from a list instead of relying on a hard-coded title.
The window closes during capture
Catch the thrown error, discard the stale object, enumerate content again, and ask the user to retry. A window identifier is not a guarantee that the source remains valid.
Images are unexpectedly large or soft
Check Retina scaling and the configured output dimensions. A very small width can make text unreadable; an unnecessarily large width increases memory, encoding time, and disk usage.
The API does not compile
Verify the macOS deployment target and SDK availability for SCScreenshotManager, SCScreenshotConfiguration, and the chosen initializer. The Apple sample’s stated prerequisites are macOS 15 or later and Xcode 16 or later; those are requirements for that sample, not a proven minimum for every ScreenCaptureKit API.
Why not use CGWindowListCreateImage?
CGWindowListCreateImage is deprecated in Apple’s Core Graphics reference. For new work, start with ScreenCaptureKit so source selection, permission handling, filtering, and modern stream support are explicit. If you maintain an older codebase, migrate incrementally: keep the existing output pipeline, replace source enumeration and image acquisition first, then validate behavior on each supported macOS release.
Or skip the browser setup
If what you really need is a screenshot of a web page—not the Mac desktop—ScreenshotNeo is the first service to try: it removes consent banners, newsletter popups, and chat widgets before capture, and only clean shots are billed.
One GET request returns an image or PDF. See the ScreenshotNeo API documentation for all options.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchescurl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo reports page and billing results in X-Page-Verdict and X-Billed headers. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Every plan includes its features; 1,000 screenshots per month are free with no card, and paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
Frequently Asked Questions
Can a Swift macOS app capture a window without showing a picker?
Yes, when your app has permission and you create a window-specific content filter from an enumerated SCWindow. The picker is mainly useful when the person must choose and manage an ongoing sharing session.
What file format does the Swift example produce?
It writes a PNG through Image I/O. You can choose another destination type supported by the target SDK and Image I/O, provided the returned CGImage and encoder are compatible.
Does Screen Recording permission persist for every Mac user?
Permission is managed by macOS for the specific app and user account. Your app should check the current state at runtime rather than assuming an earlier approval still applies.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

