[swift] screenshot

Viewer

copydownloadembedprintName: screenshot
  1. import UIKit
  2. import Flutter
  3.  
  4. @UIApplicationMain
  5. @objc class AppDelegate: FlutterAppDelegate, FlutterStreamHandler {
  6.  
  7.     let overlayController = UIViewController()
  8.     let textField = UITextField()
  9.     var eventSink: FlutterEventSink?
  10.  
  11.     override func application(
  12.         _ application: UIApplication,
  13.         didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  14.     ) -> Bool {
  15.         self.window.makeSecure()
  16.         startTimer()
  17.         if #available(iOS 10.0, *) {
  18.             UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
  19.         }
  20.         makeSecureYourScreen()
  21.         // Configure ScreenRecordHandler if it's defined
  22.         // ScreenRecordHandler.shared.configure()
  23.  
  24.         GeneratedPluginRegistrant.register(with: self)
  25.  
  26.         NotificationCenter.default.addObserver(self, selector: #selector(screenRecordingStatusChanged), name: UIScreen.capturedDidChangeNotification, object: nil)
  27.         NotificationCenter.default.addObserver(self, selector: #selector(handleScreenshot), name: UIApplication.userDidTakeScreenshotNotification, object: nil)
  28.  
  29.         DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
  30.             if UIScreen.main.isCaptured {
  31.                 self.displayOverlayControllerWith(message: "Screen recording is not allowed while using the app. Kindly turn off the screen recording to continue using the app.")
  32.             }
  33.         }
  34.  
  35.         // Access FlutterViewController through the window property
  36.         if let controller = window?.rootViewController as? FlutterViewController {
  37.             let chargingChannel = FlutterEventChannel(name: "hurab/screentshot", binaryMessenger: controller.binaryMessenger)
  38.             chargingChannel.setStreamHandler(self)
  39.         } else {
  40.             print("Error: FlutterViewController not found.")
  41.         }
  42.  
  43.         return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  44.     }
  45.  
  46.     @objc func screenRecordingStatusChanged() {
  47.         if UIScreen.main.isCaptured || isScreenshotBlocked() {
  48.             self.displayOverlayControllerWith(message: "Screenshots are not allowed while using the app.")
  49.         } else {
  50.             self.overlayController.dismiss(animated: false, completion: nil)
  51.         }
  52.     }
  53.  
  54.     fileprivate func displayOverlayControllerWith(message: String) {
  55.         if let rootWindow = UIApplication.shared.windows.first {
  56.             self.overlayController.view.backgroundColor = .white
  57.             self.overlayController.modalPresentationStyle = .fullScreen
  58.             let screenWidth = UIScreen.main.bounds.width
  59.             let screenHeight = UIScreen.main.bounds.height - (rootWindow.safeAreaInsets.top + rootWindow.safeAreaInsets.bottom)
  60.             let frameOfLabel = CGRect(x: 20, y: screenHeight/2 - 100, width: screenWidth - 40, height: 200)
  61.             if let labelMessage = self.overlayController.view.viewWithTag(1010) asUILabel {
  62.                 labelMessage.text = message
  63.             } else {
  64.                 let labelMessage = UILabel(frame: frameOfLabel)
  65.                 labelMessage.tag = 1010
  66.                 labelMessage.numberOfLines = 0
  67.                 labelMessage.font = UIFont.systemFont(ofSize: 18, weight: .regular)
  68.                 labelMessage.text = message
  69.                 labelMessage.textColor = .black
  70.                 labelMessage.textAlignment = .center
  71.                 self.overlayController.view.addSubview(labelMessage)
  72.             }
  73.             rootWindow.rootViewController?.present(self.overlayController, animated: false, completion: nil)
  74.         }
  75.     }
  76.  
  77.     override func applicationWillResignActive(
  78.         _ application: UIApplication
  79.     ) {
  80.         print("applicationWillResignActive")
  81.         self.window.isHidden = isRecording()
  82.     }
  83.  
  84.     override func applicationDidBecomeActive(
  85.         _ application: UIApplication
  86.     ) {
  87.         print("applicationDidBecomeActive")
  88.         self.window.isHidden = isRecording()
  89.     }
  90.  
  91.     @objc func isRecording() -> Bool {
  92.         print("isRecording func")
  93.         for screen in UIScreen.screens {
  94.             if screen.isCaptured {
  95.                 screenshotInvoke()
  96.                 print("isRecording true")
  97.                 return true
  98.             }
  99.         }
  100.         print("isRecording false")
  101.         return false
  102.     }
  103.  
  104.     private func screenshotInvoke() {
  105.         guard let eventSink = eventSink else {
  106.             return
  107.         }
  108.         eventSink("true")
  109.     }
  110.  
  111.     override func applicationWillTerminate(_ application: UIApplication) {
  112.         NotificationCenter.default.removeObserver(self)
  113.     }
  114.  
  115.     private func makeSecureYourScreen() {
  116.         if !self.window.subviews.contains(textField) {
  117.             self.window.addSubview(textField)
  118.             textField.centerYAnchor.constraint(equalTo: self.window.centerYAnchor).isActive = true
  119.             textField.centerXAnchor.constraint(equalTo: self.window.centerXAnchor).isActive = true
  120.             self.window.layer.superlayer?.addSublayer(textField.layer)
  121.             textField.layer.sublayers?.first?.addSublayer(self.window.layer)
  122.         }
  123.     }
  124.  
  125.     func startTimer() {
  126.         let timer = Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(self.isRecording), userInfo: nil, repeats: true)
  127.     }
  128.  
  129.     // MARK: - FlutterStreamHandler
  130.  
  131.     @objc func onListen(withArguments arguments: Any?, eventSink: @escaping FlutterEventSink) -> FlutterError? {
  132.         // Implement your logic when a Flutter client starts listening
  133.         // You can save the eventSink for later use
  134.         self.eventSink = eventSink
  135.         return nil
  136.     }
  137.  
  138.     @objc func onCancel(withArguments arguments: Any?) -> FlutterError? {
  139.         // Implement your logic when a Flutter client stops listening
  140.         // You can clean up any resources here
  141.         self.eventSink = nil
  142.         return nil
  143.     }
  144.  
  145.     // MARK: - Screenshot Handling
  146.  
  147.     @objc func handleScreenshot() {
  148.         // Handle screenshot event
  149.         print("Screenshot taken")
  150.         // You can show an alert or perform any action here
  151.     }
  152.  
  153.     // MARK: - Helper Method
  154.  
  155.     func isScreenshotBlocked() -> Bool {
  156.         if #available(iOS 13.0, *) {
  157.             if UIScreen.main.isCaptured || UIScreen.main.isCaptured {
  158.                 return true
  159.             }
  160.         } else {
  161.             if UIScreen.main.isCaptured {
  162.                 return true
  163.             }
  164.         }
  165.         return false
  166.     }
  167. }
  168.  
  169. extension UIWindow {
  170.     func makeSecure() {
  171.         let field = UITextField()
  172.         field.isSecureTextEntry = true
  173.         self.addSubview(field)
  174.         field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
  175.         field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
  176.         self.layer.superlayer?.addSublayer(field.layer)
  177.         field.layer.sublayers?.first?.addSublayer(self.layer)
  178.     }
  179. }
  180.  

Editor

You can edit this paste and save as new:


File Description
  • screenshot
  • Paste Code
  • 06 May-2024
  • 6.89 Kb
You can Share it: