Skip to content

Protect sensitive SwiftUI views from screenshots and screen recordings with customizable placeholders. Simple, lightweight, and easy to integrate.

License

Notifications You must be signed in to change notification settings

EmadBeyrami/SnapShield

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

23 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

SnapShield

๐Ÿ›ก๏ธ SnapShield

A lightweight Swift package that protects sensitive content in your iOS, VisionOS, MacOS and tvOS apps from screenshots, screen recordings, and screen sharing.

Swift Version Platform License SPM Compatible

๐ŸŽฏ Features

  • ๐Ÿ”’ Complete Protection - Secures content from screenshots, screen recordings, and screen sharing
  • ๐ŸŽจ Customizable Placeholders - Show custom views when content is being captured
  • โšก Easy Integration - Simple SwiftUI modifier API
  • ๐Ÿชถ Lightweight - Zero dependencies, minimal footprint
  • ๐Ÿ“ฑ Cross-Platform - Works on iOS and tvOS
  • ๐ŸŽฎ Example Project Included - Learn from real-world implementations
  • ๐ŸŽฎ Example Project Included - Learn from real-world implementations

๐Ÿ“ธ Demo

Normal View vs Screenshot

Normal View:

ScreenRecording_10-12-2025.23-52-29_1.MP4

When Screenshot/Recording:

ScreenRecording_10-12-2025.23-51-20_1.MP4

๐Ÿš€ Installation

Swift Package Manager

Option 1: Install via Xcode

  1. Open your project in Xcode
  2. Go to File โ†’ Add Package Dependencies
  3. Enter the package URL:
    https://github.com/EmadBeyrami/SnapShield.git
    
  4. Click Add Package
  5. Select your desired version (Dependency Rule)
  6. Click Add Package again to confirm

Option 2: Install via Package.swift

Add SnapShield to your Package.swift dependencies:

dependencies: [
    .package(url: "https://github.com/EmadBeyrami/SnapShield.git", from: "1.0.0")
]

Then add it to your target dependencies:

targets: [
    .target(
        name: "YourTarget",
        dependencies: ["SnapShield"]
    )
]

โšก Quick Start

After installing the package, import SnapShield and start protecting your content:

import SwiftUI
import SnapShield

struct ContentView: View {
    var body: some View {
        VStack(spacing: 20) {
            // Hide content completely
            Text("Password: MySecret123")
                .snapShield()
            
            // Show custom placeholder
            Text("Credit Card: 1234-5678-9012-3456")
                .snapShield {
                    Text("๐Ÿ”’ Protected")
                        .font(.headline)
                }
        }
    }
}

That's it! Your sensitive content is now protected from screenshots, screen recordings, and screen sharing.

๐ŸŽฎ Example Project

Want to see SnapShield in action? Check out the included example project in the repository!

The example app demonstrates:

  • Basic Protection - Simple content hiding with .snapShield()
  • Custom Placeholders - Showing custom views during screenshots
  • Bank Card Demo - Realistic credit card protection with styled placeholder
  • Multiple Protected Views - Combining different protection strategies in one screen

To run the example:

git clone https://github.com/EmadBeyrami/SnapShield.git
cd SnapShield
open SnapShieldExample/SnapShieldExample.xcodeproj

Then build and run on a simulator or device to test screenshot protection!

๐Ÿ’ก Tip: To test the protection, run the app on a real device and try taking screenshots (Power + Volume Up) or start screen recording. You'll see the protected content is replaced with either a blank view or your custom placeholder!

๐Ÿ“– Usage

Import SnapShield in your SwiftUI views:

import SwiftUI
import SnapShield

Basic Usage - Hide Content

Simply hide sensitive content when screenshots or recordings are attempted:

Text("Secret Password: 12345")
    .snapShield()

The content will be completely hidden (blank) during screenshots, screen recordings, or screen sharing.

Advanced Usage - Custom Placeholder

Show a custom view when content is being captured:

Text("Credit Card: 1234-5678-9012-3456")
    .snapShield {
        VStack {
            Image(systemName: "lock.shield")
                .font(.system(size: 60))
                .foregroundColor(.red)
            Text("Protected Content")
                .font(.headline)
                .foregroundColor(.gray)
        }
    }

๐Ÿ’ก Examples

Simple Text Placeholder

VStack {
    Text("Bank Account: 123456789")
    Text("Balance: $50,000")
}
.snapShield {
    Text("๐Ÿ”’ This content is hidden")
        .font(.title)
        .foregroundColor(.gray)
}

Image Placeholder

Image("sensitiveDocument")
    .resizable()
    .scaledToFit()
    .snapShield {
        Image("protectedPlaceholder")
            .resizable()
            .scaledToFit()
    }

Styled Placeholder

PersonalInfoView()
    .snapShield {
        ZStack {
            Color.black
            VStack(spacing: 20) {
                Image(systemName: "eye.slash.fill")
                    .font(.system(size: 100))
                    .foregroundColor(.white)
                Text("Content Protected")
                    .font(.title)
                    .foregroundColor(.white)
                Text("This information cannot be captured")
                    .font(.caption)
                    .foregroundColor(.gray)
            }
        }
    }

Bank Card Example

Protect sensitive financial information with a professional placeholder:

struct BankCardView: View {
    var body: some View {
        // Your card UI design
        ZStack {
            LinearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing)
            VStack(alignment: .leading, spacing: 20) {
                Text("4532 1234 5678 9010")
                    .font(.system(size: 24, design: .monospaced))
                Text("JOHN DOE")
                // ... more card details
            }
        }
        .snapShield {
            // Placeholder shown in screenshots
            ZStack {
                LinearGradient(colors: [.gray, .gray.opacity(0.5)], startPoint: .topLeading, endPoint: .bottomTrailing)
                VStack(spacing: 15) {
                    Image(systemName: "lock.shield.fill")
                        .font(.system(size: 50))
                        .foregroundColor(.white)
                    Text("Card Information Protected")
                        .font(.headline)
                        .foregroundColor(.white)
                }
            }
        }
    }
}

Multiple Protected Views

You can protect different sections with different strategies on the same screen:

ScrollView {
    VStack(spacing: 20) {
        // Section 1: Completely hidden
        VStack {
            Text("Password: super_secret_123")
        }
        .padding()
        .background(Color.red.opacity(0.1))
        .snapShield()
        
        // Section 2: Custom placeholder
        VStack {
            Text("API Key: sk_live_abcd1234efgh5678")
        }
        .padding()
        .background(Color.orange.opacity(0.1))
        .snapShield {
            VStack {
                Image(systemName: "key.fill")
                    .font(.largeTitle)
                Text("API Key Hidden")
            }
            .padding()
        }
        
        // Section 3: Not protected (public info)
        VStack {
            Text("Public Info: This is visible in screenshots")
        }
        .padding()
        .background(Color.green.opacity(0.1))
    }
}

Custom View Component

Create reusable placeholder components:

struct ProtectedPlaceholder: View {
    var body: some View {
        VStack(spacing: 16) {
            Image(systemName: "hand.raised.fill")
                .font(.system(size: 80))
                .foregroundColor(.red)
            Text("Screenshot Blocked")
                .font(.title2)
                .bold()
            Text("This content is protected for your security")
                .font(.body)
                .multilineTextAlignment(.center)
                .foregroundColor(.secondary)
        }
        .padding()
    }
}

// Usage
SensitiveDataView()
    .snapShield {
        ProtectedPlaceholder()
    }

Alert-Style Protection

VStack(spacing: 15) {
    Image(systemName: "creditcard.fill")
        .font(.system(size: 50))
    Text("Credit Card: 1234-5678-9012-3456")
    Text("CVV: 123")
    Text("Exp: 12/25")
}
.padding()
.snapShield {
    ZStack {
        Color.red.opacity(0.2)
        VStack(spacing: 15) {
            Image(systemName: "exclamationmark.shield.fill")
                .font(.system(size: 60))
                .foregroundColor(.red)
            Text("Protected Content")
                .font(.headline)
            Text("Screenshots are not allowed")
                .font(.caption)
        }
    }
}

For more examples, check out the SnapShieldExample project in the repository!

๐Ÿ”ง How It Works

SnapShield leverages iOS's secure text field behavior to protect your content. When you mark a view with .snapShield():

  1. The content is rendered inside a secure container (similar to password fields)
  2. During screenshots, screen recordings, or screen sharing, the secure container becomes invisible
  3. If you've provided a custom placeholder, it appears in place of the hidden content
  4. Normal app usage is unaffected - users see and interact with content normally

This technique works for:

  • ๐Ÿ“ธ Screenshots - iOS system screenshots
  • ๐ŸŽฅ Screen Recording - Built-in screen recording
  • ๐Ÿ–ฅ๏ธ Screen Sharing - AirPlay, screen mirroring, and video calls

๐Ÿ“‹ Requirements

  • iOS 16.0+ / tvOS 16.0+
  • Swift 6.2+
  • Xcode 16.0+

๐ŸŽฏ Use Cases

SnapShield is perfect for protecting:

  • ๐Ÿ’ณ Credit card information
  • ๐Ÿ” Passwords and authentication codes
  • ๐Ÿ’ฐ Bank account details
  • ๐Ÿ“„ Personal identification documents
  • ๐Ÿ’Š Medical records
  • ๐Ÿ“Š Confidential business data
  • ๐Ÿ”‘ API keys and secrets
  • ๐Ÿ“ฑ 2FA codes

โš ๏ธ Important Notes

๐Ÿ“ Note: This is a clever workaround since Apple doesn't provide an official API for content protection. While it works perfectly now, there's a possibility it might stop working in future iOS updates. I'll do my best to update the package with alternative solutions if that happens! ๐Ÿ› ๏ธ

  • SnapShield prevents casual content capture but is not a security guarantee
  • Determined users with physical access or jailbroken devices may bypass protections
  • Use SnapShield as part of a comprehensive security strategy
  • Always follow security best practices for handling sensitive data

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

๐Ÿ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ‘จโ€๐Ÿ’ป Author

Emad Beyrami

๐Ÿ™ Acknowledgments

  • Inspired by the need for better content protection in modern iOS apps
  • Thanks to the Swift community for feedback and suggestions

๐Ÿ“ฎ Support

If you have any questions or issues, please:


Made with โค๏ธ by Emad Beyrami

โญ If you find SnapShield useful, please consider giving it a star on GitHub! โญ