iOS development
screen capture protection
app security
mobile app development
Swift programming

Prevent screen capture in an iOS app

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

On iOS, you generally cannot completely prevent a user from taking a screenshot of your app. Apple does not expose a public API that disables screenshots globally for an app the way some other platforms expose secure-window flags.

What you can do is reduce the value of captured content, detect some capture events, and hide or blur sensitive data when screen recording or mirroring is active. That is the realistic security model on iOS.

You Cannot Reliably Block Screenshots

This is the most important fact to get right: there is no public iOS API that says "disable screenshots for this screen."

You can observe that a screenshot happened after the fact, but not block it beforehand.

swift
1import UIKit
2
3NotificationCenter.default.addObserver(
4    forName: UIApplication.userDidTakeScreenshotNotification,
5    object: nil,
6    queue: .main
7) { _ in
8    print("A screenshot was taken")
9}

This is useful for auditing or user messaging, but it does not stop the screenshot itself.

Handle Screen Recording and Mirroring

For live capture scenarios such as screen recording or AirPlay mirroring, iOS gives you a better signal through UIScreen.main.isCaptured and the related notification.

swift
1import UIKit
2
3final class SecureViewController: UIViewController {
4    private let shieldView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8
9        shieldView.frame = view.bounds
10        shieldView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
11        shieldView.isHidden = true
12        view.addSubview(shieldView)
13
14        NotificationCenter.default.addObserver(
15            self,
16            selector: #selector(captureChanged),
17            name: UIScreen.capturedDidChangeNotification,
18            object: nil
19        )
20
21        updateCaptureState()
22    }
23
24    @objc private func captureChanged() {
25        updateCaptureState()
26    }
27
28    private func updateCaptureState() {
29        shieldView.isHidden = !UIScreen.main.isCaptured
30    }
31}

This does not prevent all screen capture forever, but it does let you hide sensitive content during active capture sessions.

Protect Content When the App Goes to Background

Another common leak path is the app switcher snapshot. When the app moves to the background, iOS may create a system snapshot for the multitasking UI. If your screen contains sensitive content, cover it before the app resigns active state.

swift
1import UIKit
2
3final class PrivacyWindowController {
4    private let cover = UIView()
5
6    init(window: UIWindow) {
7        cover.frame = window.bounds
8        cover.backgroundColor = .systemBackground
9        cover.autoresizingMask = [.flexibleWidth, .flexibleHeight]
10        cover.isHidden = true
11        window.addSubview(cover)
12
13        NotificationCenter.default.addObserver(
14            self,
15            selector: #selector(hideSensitiveUI),
16            name: UIApplication.willResignActiveNotification,
17            object: nil
18        )
19
20        NotificationCenter.default.addObserver(
21            self,
22            selector: #selector(showSensitiveUI),
23            name: UIApplication.didBecomeActiveNotification,
24            object: nil
25        )
26    }
27
28    @objc private func hideSensitiveUI() { cover.isHidden = false }
29    @objc private func showSensitiveUI() { cover.isHidden = true }
30}

This protects against snapshot exposure in the app switcher, which is a different concern from button-triggered screenshots.

Design for Damage Reduction

Because you cannot guarantee screenshot prevention, you should also think in terms of reducing exposure:

  • mask part of account numbers or personal data
  • require re-authentication for especially sensitive screens
  • avoid displaying secrets longer than necessary
  • watermark sensitive views if audit deterrence matters

That design mindset is often more effective than searching for a nonexistent "disable screenshot" switch.

Common Pitfalls

  • Claiming that iOS lets you fully block screenshots with a public API.
  • Detecting userDidTakeScreenshotNotification and assuming that means the capture was prevented.
  • Ignoring UIScreen.main.isCaptured, which is useful for live recording or mirroring cases.
  • Forgetting to protect app-switcher snapshots when the app resigns active state.
  • Relying only on client-side UI protection when the real security need is broader than screen capture alone.

Summary

  • iOS does not provide a public API to fully prevent screenshots.
  • You can detect screenshots after they happen with UIApplication.userDidTakeScreenshotNotification.
  • You can react to active recording or mirroring with UIScreen.main.isCaptured.
  • Cover sensitive content when the app goes to the background to protect app-switcher snapshots.
  • For real protection, design the UI so captured content is less sensitive in the first place.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.