Today I want to share a fresh new Swift Package SDK that helps you to hide sensitive informations on your app, like banking apps, in a easy way!
You’ll be notified via callback (optional) when a defined rule occur, and apply the right custom protection you prefer or simply use the integrated blur that cover your app automatically.
Available protections
While writing this post, the SDK provide these protections callbacks:
QuickTime screen recording | |
iOS screen recording | |
iOS native Airplay / Mirroring | |
Background app screenshot cache | |
User taken screenshots |
How it works
Simply, add a view on top of your root window, in order to hide sensitive content behind.
Imagine that you app is this one:
When one of the defined rules to apply is recognized, a custom view or a blurred view can appear on top:
You can handle more of these rules, the code is on Github, feel free to open merge requests.
You can also apply a custom behavior when detected (show an alert, send an API request, or what you prefer…).
Code usage.
Add the repo directly in Swift Package Manager through XCode and import the SDK (generally in SceneDelegate or AppDelegate, because you need the window):
import ScreenSecuritySDK
Next in your sceneWillConnect, initialize the SDK:
var screenSecurity: ScreenSecurity?
[...]
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
screenSecurity = ScreenSecurity( window! )
}
Creating security rules
Allowed types are defined in this enum:
case quickTime
case screenRecording
case mirroring
case screenCache
case screenshot
You can create the rules you prefer, in this way:
let mirroringRule = ScreenSecurityRules {
$0.type = .mirroring
$0.callback = self.mirrorDetected
}
In every rule you can add a type, that is mandatory and a callback that is optional and can be used inline or with a custom defined function (as you prefer).
// example as custom callback
var mirrorDetected: (Any?, Bool) -> Void =
{ (arg: Any?, status: Bool) -> Void in
print("mirrorDetected: \(status)")
}
// example of inline callback
let mirroringRule = ScreenSecurityRules {
$0.type = .mirroring
$0.callback = (arg: Any?, status: Bool) -> Void in {
print("mirrorDetected: \(status)")
}
}
ScreenCache extra settings
In case you need the screenCache rule, you need also to add the sceneDelegate or appDelegate param:
let screenCacheRule = ScreenSecurityRules {
$0.type = .screenCache
$0.callback = self.screenCacheDetected
$0.sceneDelegate = self // one of these
$0.appDelegate = self // one of these
}
You need also to inform the SDK when the app-lifecycle methods are called, and you need to call the screenSecurity?.listen()
method in these delegates:
func sceneDidBecomeActive(_ scene: UIScene) {
screenSecurity?.listen(type: .didBecomeActive)
}
func sceneWillResignActive(_ scene: UIScene) {
screenSecurity?.listen(type: .willResignActive)
}
func sceneWillEnterForeground(_ scene: UIScene) {
screenSecurity?.listen(type: .willEnterForeground)
}
func sceneDidEnterBackground(_ scene: UIScene) {
screenSecurity?.listen(type: .didEnterBackground)
}
If you need to go deep on how iOS save automatically the screenshot of your app when is in background, take a read here: https://www.albertopasca.it/whiletrue/ios-data-leakage-app-background-cache/ .
Composing rules
Now, create the rules your prefer and next configure the SDK passing the rules and the settings needed:
var rules = [ScreenSecurityRules]()
rules = [
mirroringRule,
quickTimeRule,
screenRecordingRule,
screenCacheRule,
screenshotRule
]
and pass it to initializer
screenSecurity?.configure(rules: rules, autoBlur: true)
The configure method take as parameters:
rules: your custom created rules
autoBlur: to use integrated automatic blur
customView: UIVIew, if you want to use your custom view + logo
Add a custom view instead of blur
If you prefer to use your custom view, you can pass it creating a new UIView, simply:
let customView = UIView(frame: self.window!.bounds)
customView.backgroundColor = .red.withAlphaComponent(0.9)
let image = UIImage(named: "logo")!
let midX = UIScreen.main.bounds.midX - 200 / 2
let midY = UIScreen.main.bounds.midY - 100
let imageView = UIImageView(frame: CGRect(
x: midX,
y: midY,
width: 200,
height: 100))
imageView.image = image
imageView.contentMode = .scaleAspectFit
imageView.backgroundColor = .clear
customView.addSubview(imageView)
screenSecurity?.configure(rules: rules, autoBlur: false, customOverlay: customView)
Build and run.
Open points:
- user screenshots actually are not blocked, only informed. Hint: if your app use the camera roll, you can delete latest taken picture automatically (that is the screenshot)… 🤫
- SDK is under development
Merge requests are welcome!
Repo GitHub / Swift Package Manager here: https://github.com/elpsk/ScreenSecuritySDK
Inspired by: https://screenshieldkit.com
App cache: https://www.albertopasca.it/whiletrue/ios-data-leakage-app-background-cache/)