182 lines
6.7 KiB
Swift
182 lines
6.7 KiB
Swift
import Flutter
|
|
import UIKit
|
|
import ScreenProtectorKit
|
|
|
|
public class IOSNoScreenshotPlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
|
|
private var screenProtectorKit: ScreenProtectorKit? = nil
|
|
private static var methodChannel: FlutterMethodChannel? = nil
|
|
private static var eventChannel: FlutterEventChannel? = nil
|
|
private static var preventScreenShot: Bool = false
|
|
private var eventSink: FlutterEventSink? = nil
|
|
private var lastSharedPreferencesState: String = ""
|
|
private var hasSharedPreferencesChanged: Bool = false
|
|
|
|
private static let ENABLESCREENSHOT = false
|
|
private static let DISABLESCREENSHOT = true
|
|
|
|
private static let preventScreenShotKey = "preventScreenShot"
|
|
private static let methodChannelName = "com.flutterplaza.no_screenshot_methods"
|
|
private static let eventChannelName = "com.flutterplaza.no_screenshot_streams"
|
|
private static let screenshotPathPlaceholder = "screenshot_path_placeholder"
|
|
|
|
init(screenProtectorKit: ScreenProtectorKit) {
|
|
self.screenProtectorKit = screenProtectorKit
|
|
super.init()
|
|
|
|
// Restore the saved state from UserDefaults
|
|
var fetchVal = UserDefaults.standard.bool(forKey: IOSNoScreenshotPlugin.preventScreenShotKey)
|
|
updateScreenshotState(isScreenshotBlocked: fetchVal)
|
|
}
|
|
|
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
|
methodChannel = FlutterMethodChannel(name: methodChannelName, binaryMessenger: registrar.messenger())
|
|
eventChannel = FlutterEventChannel(name: eventChannelName, binaryMessenger: registrar.messenger())
|
|
|
|
let window = UIApplication.shared.delegate?.window
|
|
let screenProtectorKit = ScreenProtectorKit(window: window as? UIWindow)
|
|
screenProtectorKit.configurePreventionScreenshot()
|
|
|
|
let instance = IOSNoScreenshotPlugin(screenProtectorKit: screenProtectorKit)
|
|
registrar.addMethodCallDelegate(instance, channel: methodChannel!)
|
|
eventChannel?.setStreamHandler(instance)
|
|
registrar.addApplicationDelegate(instance)
|
|
}
|
|
|
|
public func applicationWillResignActive(_ application: UIApplication) {
|
|
persistState()
|
|
}
|
|
|
|
public func applicationDidBecomeActive(_ application: UIApplication) {
|
|
fetchPersistedState()
|
|
}
|
|
|
|
public func applicationWillEnterForeground(_ application: UIApplication) {
|
|
fetchPersistedState()
|
|
}
|
|
|
|
public func applicationDidEnterBackground(_ application: UIApplication) {
|
|
persistState()
|
|
}
|
|
|
|
public func applicationWillTerminate(_ application: UIApplication) {
|
|
persistState()
|
|
}
|
|
|
|
func persistState() {
|
|
// Persist the state when changed
|
|
UserDefaults.standard.set(IOSNoScreenshotPlugin.preventScreenShot, forKey: IOSNoScreenshotPlugin.preventScreenShotKey)
|
|
print("Persisted state: \(IOSNoScreenshotPlugin.preventScreenShot)")
|
|
updateSharedPreferencesState("")
|
|
}
|
|
|
|
func fetchPersistedState() {
|
|
// Restore the saved state from UserDefaults
|
|
var fetchVal = UserDefaults.standard.bool(forKey: IOSNoScreenshotPlugin.preventScreenShotKey) ? IOSNoScreenshotPlugin.DISABLESCREENSHOT :IOSNoScreenshotPlugin.ENABLESCREENSHOT
|
|
updateScreenshotState(isScreenshotBlocked: fetchVal)
|
|
print("Fetched state: \(IOSNoScreenshotPlugin.preventScreenShot)")
|
|
}
|
|
|
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
switch call.method {
|
|
case "screenshotOff":
|
|
shotOff()
|
|
result(true)
|
|
case "screenshotOn":
|
|
shotOn()
|
|
result(true)
|
|
case "toggleScreenshot":
|
|
IOSNoScreenshotPlugin.preventScreenShot ? shotOn(): shotOff()
|
|
result(true)
|
|
case "startScreenshotListening":
|
|
startListening()
|
|
result("Listening started")
|
|
case "stopScreenshotListening":
|
|
stopListening()
|
|
result("Listening stopped")
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
private func shotOff() {
|
|
IOSNoScreenshotPlugin.preventScreenShot = IOSNoScreenshotPlugin.DISABLESCREENSHOT
|
|
screenProtectorKit?.enabledPreventScreenshot()
|
|
persistState()
|
|
}
|
|
|
|
private func shotOn() {
|
|
IOSNoScreenshotPlugin.preventScreenShot = IOSNoScreenshotPlugin.ENABLESCREENSHOT
|
|
screenProtectorKit?.disablePreventScreenshot()
|
|
persistState()
|
|
}
|
|
|
|
private func startListening() {
|
|
NotificationCenter.default.addObserver(self, selector: #selector(screenshotDetected), name: UIApplication.userDidTakeScreenshotNotification, object: nil)
|
|
persistState()
|
|
}
|
|
|
|
private func stopListening() {
|
|
NotificationCenter.default.removeObserver(self, name: UIApplication.userDidTakeScreenshotNotification, object: nil)
|
|
persistState()
|
|
}
|
|
|
|
@objc private func screenshotDetected() {
|
|
print("Screenshot detected")
|
|
updateSharedPreferencesState(IOSNoScreenshotPlugin.screenshotPathPlaceholder)
|
|
}
|
|
|
|
private func updateScreenshotState(isScreenshotBlocked: Bool) {
|
|
if isScreenshotBlocked {
|
|
screenProtectorKit?.enabledPreventScreenshot()
|
|
} else {
|
|
screenProtectorKit?.disablePreventScreenshot()
|
|
}
|
|
}
|
|
|
|
private func updateSharedPreferencesState(_ screenshotData: String) {
|
|
let map: [String: Any] = [
|
|
"is_screenshot_on": IOSNoScreenshotPlugin.preventScreenShot,
|
|
"screenshot_path": screenshotData,
|
|
"was_screenshot_taken": !screenshotData.isEmpty
|
|
]
|
|
let jsonString = convertMapToJsonString(map)
|
|
if lastSharedPreferencesState != jsonString {
|
|
hasSharedPreferencesChanged = true
|
|
lastSharedPreferencesState = jsonString
|
|
}
|
|
}
|
|
|
|
private func convertMapToJsonString(_ map: [String: Any]) -> String {
|
|
if let jsonData = try? JSONSerialization.data(withJSONObject: map, options: .prettyPrinted) {
|
|
return String(data: jsonData, encoding: .utf8) ?? ""
|
|
}
|
|
return ""
|
|
}
|
|
|
|
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
eventSink = events
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
self.screenshotStream()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
eventSink = nil
|
|
return nil
|
|
}
|
|
|
|
private func screenshotStream() {
|
|
if hasSharedPreferencesChanged {
|
|
eventSink?(lastSharedPreferencesState)
|
|
hasSharedPreferencesChanged = false
|
|
}
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
self.screenshotStream()
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
screenProtectorKit?.removeAllObserver()
|
|
}
|
|
}
|