GreedyKit is a set of ready-to-use UIKit and SwiftUI components to prevent sensitive media data, such as images or videos, from being exposed by screen capture tools on iOS.
While building a video player for one of the enterprise projects, I needed a way to prevent users from taking screenshots or recording what was on the screen. Apple’s FairPlay DRM secures streamed media only, so I turned to AVSampleBufferDisplayLayer, which natively supports what I needed.
GreedyKit packages this technique, allowing you to protect media with a single property toggle without DRM servers or certificates.
- iOS/iPadOS 13.0 and later
- Swift 6.0 and later
- Xcode 16.0 and later
You can use Swift Package Manager to install GreedyKit using Xcode:
- Open your project in Xcode
- Open "File" -> "Add Packages..."
- Paste the repository URL: https://github.com/igooor-bb/GreedyKit
- Click "Next" a couple of times and finish the process
Alternatively, add the dependency to your Package.swift:
.package(url: "https://github.com/igooor-bb/GreedyKit", from: "<version>")After you have installed the package, import it into the project in the usual way:
import GreedyKitThe package includes components for displaying images and videos that can change the capture mode on demand.
You can find an example of how to use them in Examples/GreedyKitExample.
By default, media keeps its aspect ratio and remains fully visible inside the view. For layouts that need edge-to-edge protected content, set contentGravity explicitly:
GreedyPlayer(avPlayer, preventsCapture: true, contentGravity: .fill)UIKit views expose the same option as a mutable property.
In UIKit, you can use the GreedyImageView wrapper around your UIImage similar to regular UIImageView:
let imageView = GreedyImageView()
imageView.image = UIImage(named: "SecretImage")
// Block capture at any time:
imageView.preventsCapture = trueIn SwiftUI, you can simply use GreedyImage component with your UIImage inside:
VStack {
GreedyImage(uiImage, preventsCapture: true)
}In UIKit, you can use the GreedyPlayerView wrapper around your AVPlayer:
let player = AVPlayer(url: videoURL)
let playerView = GreedyPlayerView()
playerView.player = player
// Start playback:
player.play()
// Block capture at any time:
playerView.preventsCapture = trueIn SwiftUI, you just need to create a GreedyPlayer within your view hierarchy and pass an AVPlayer, whose content it will draw:
VStack {
GreedyPlayer(avPlayer, preventsCapture: true)
}GreedyKit is not a DRM system and does not manage content licenses, keys, or streaming protection.
Capture prevention behavior is provided by Apple's media rendering APIs and may differ between simulator and physical devices. Validate critical flows on real devices before shipping.
To contribute, use the follow "fork-and-pull" git workflow:
- Fork the repository on github
- Clone the project to your own machine
- Commit changes to your own branch
- Push your work back up to your fork
- Submit a pull request so that I can review your changes
NOTE: Be sure to merge the latest from "upstream" before making a pull request!
GreedyKit is available under the MIT license. See the LICENSE file for more info.