index.uts 4.8 KB
Newer Older
lizhongyi_'s avatar
lizhongyi_ 已提交
1 2
import { NotificationCenter } from 'Foundation';
import { CGRect } from "CoreFoundation";
3
import { UIApplication, UIView, UITextField, UIScreen, UIDevice } from "UIKit"
4
import { UTSiOS } from "DCloudUTSFoundation"
lizhongyi_'s avatar
lizhongyi_ 已提交
5 6
import { DispatchQueue } from 'Dispatch';
import { SetUserCaptureScreenOptions, OnUserCaptureScreenCallbackResult, OnUserCaptureScreen, OffUserCaptureScreen, SetUserCaptureScreen, UserCaptureScreenCallback, SetUserCaptureScreenSuccess, SetUserCaptureScreenFail  } from "../interface.uts"
7 8 9 10 11

/**
	* 定义监听截屏事件工具类
	*/
class CaptureScreenTool {
12 13
	static listener : UserCaptureScreenCallback | null;
	static secureView : UIView | null;
14 15

	// 监听截屏
16
	static listenCaptureScreen(callback : UserCaptureScreenCallback | null) {
17
		this.listener = callback
18
 
19 20 21 22 23 24 25 26 27
		// 注册监听截屏事件及回调方法
		// target-action 回调方法需要通过 Selector("方法名") 构建
		const method = Selector("userDidTakeScreenshot")
		NotificationCenter.default.addObserver(this, selector = method, name = UIApplication.userDidTakeScreenshotNotification, object = null)
	}

	// 捕获截屏回调的方法
	// target-action 的方法前需要添加 @objc 前缀
	@objc static userDidTakeScreenshot() {
28
		// 回调
29
		const res: OnUserCaptureScreenCallbackResult = {
30 31
		}
		this.listener?.(res)
32 33 34
	}

	// 移除监听事件
35
	static removeListen(callback : UserCaptureScreenCallback | null) {
lizhongyi_'s avatar
lizhongyi_ 已提交
36
		this.listener = null
37
		NotificationCenter.default.removeObserver(this)
38 39 40
	}

	static createSecureView() : UIView | null {
lizhongyi_'s avatar
lizhongyi_ 已提交
41
		let field = new UITextField(frame = CGRect.zero)
42
		field.isSecureTextEntry = true
43 44 45 46 47 48 49
		if (field.subviews.length > 0 && UIDevice.current.systemVersion != '15.1') {
			let view = field.subviews[0]
			view.subviews.forEach((item) => {
				item.removeFromSuperview()
			})
			view.isUserInteractionEnabled = true
			return view
50 51 52 53 54
		}
		return null
	}

	// 开启防截屏
55
	static onAntiScreenshot(option : SetUserCaptureScreenOptions) {
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
		// uts方法默认会在子线程中执行,涉及 UI 操作必须在主线程中运行,通过 DispatchQueue.main.async 方法可将代码在主线程中运行
		DispatchQueue.main.async(execute = () : void => {
			let secureView = this.createSecureView()
			let window = UTSiOS.getKeyWindow()
			let rootView = window.rootViewController == null ? null : window.rootViewController!.view
			if (secureView != null && rootView != null) {
				let rootSuperview = rootView!.superview
				if (rootSuperview != null) {
					this.secureView = secureView
					rootSuperview!.addSubview(secureView!)
					rootView!.removeFromSuperview()
					secureView!.addSubview(rootView!)
					let rect = rootView!.frame
					secureView!.frame = UIScreen.main.bounds
					rootView!.frame = rect
				}
72
			}
73
			let res: SetUserCaptureScreenSuccess = {
74 75 76 77 78 79 80
			}
			option.success?.(res)
			option.complete?.(res)
		})
	}

	// 关闭防截屏
81
	static offAntiScreenshot(option : SetUserCaptureScreenOptions) {
82 83 84 85 86 87 88 89 90 91 92 93
		DispatchQueue.main.async(execute = () : void => {
			if (this.secureView != null) {
				let window = UTSiOS.getKeyWindow()
				let rootView = window.rootViewController == null ? null : window.rootViewController!.view
				if (rootView != null && this.secureView!.superview != null) {
					let rootSuperview = this.secureView!.superview
					if (rootSuperview != null) {
						rootSuperview!.addSubview(rootView!)
						this.secureView!.removeFromSuperview()
					}
				}
				this.secureView = null
94
			}
95
			let res: SetUserCaptureScreenSuccess = {
96 97 98 99 100 101 102 103 104 105
			}
			option.success?.(res)
			option.complete?.(res)
		})
	}
}

/**
	* 开启截图监听
	*/
106
export const onUserCaptureScreen : OnUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
107 108 109 110 111 112
	CaptureScreenTool.listenCaptureScreen(callback)
}

/**
	* 关闭截屏监听
	*/
113
export const offUserCaptureScreen : OffUserCaptureScreen = function (callback : UserCaptureScreenCallback | null) {
114 115 116 117 118 119
	CaptureScreenTool.removeListen(callback)
}

/**
	* 开启/关闭防截屏
	*/
120 121
export const setUserCaptureScreen : SetUserCaptureScreen = function (options : SetUserCaptureScreenOptions) {
	if (UIDevice.current.systemVersion < "13.0") {
122
		let res: SetUserCaptureScreenFail = {
123 124 125 126
			errCode: 12001,
			errSubject: "uni-usercapturescreen",
			errMsg: "setUserCaptureScreen:system not support"
		}
127 128 129
		options.fail?.(res);
		options.complete?.(res);

130
	} else if (UIDevice.current.systemVersion == "15.1") {
131
		let res: SetUserCaptureScreenFail = {
132 133 134 135
			errCode: 12010,
			errSubject: "uni-usercapturescreen",
			errMsg: "setUserCaptureScreen:system internal error"
		}
136 137 138
		options.fail?.(res);
		options.complete?.(res);
	} else {
139
		if (options.enable == true) {
140
			CaptureScreenTool.offAntiScreenshot(options)
141 142
		} else {
			CaptureScreenTool.onAntiScreenshot(options)
143 144 145
		}
	}
}
lizhongyi_'s avatar
lizhongyi_ 已提交
146