背景
如何玩转“屏幕时间”
- “屏幕时间”是什么?
第一性原理:行为数据 + 干扰抑制 + 家长监管
促进“意图性使用”,减少“无意识沉迷”,将数字设备的使用权和控制权交还给用户及其监护人。 其核心是 “知情”与“选择”。
- 知情(Awareness): 通过数据可视化(图表、报告),客观反映设备使用模式,打破“时间黑洞”。
- 选择(Choice): 提供工具(App限额、停用时间、通信限制、内容与隐私限制),让用户有能力基于“知情”做出符合自身价值观的调整。
- 尊重(Respect): 设计上平衡控制与自主。例如,限额到期时可申请“更多时间”,系统会向家长发送请求,而非粗暴切断。
2. WKWebView有什么问题?
- WKWebView通用报错ErrorView遮挡问题
- 授权二次Present不能正常弹出问题
使用教程
- 家人共享-创建儿童账号:
-
准备邮箱、手机号(可以使用家长账号对应的手机号)
-
设置年龄(实际年龄,不然更改年龄特麻烦)
- 配置-屏幕使用时间
-
家长账号
-
统计:行为数据
-
限制:添加使用限制(“达到限额时阻止使用”打开时,才能使用“授权更多时间”)
-
监管
-
限制App安装、删除
-
屏幕距离-提醒:提醒儿童保持推荐距离,降低儿童近视风险
-
-
- 请求/授权,更多时间
-
儿童账号:请求更多时间
-
家长-授权更多时间
- 关闭-屏幕使用时间
- 家长账号
设置-屏幕时间-找到儿童账号(小孩名)-管理屏幕时间-停止管理“小孩名”的屏幕时间
- 退出儿童账号
设备上,儿童账号,“退出登录”显示“由于访问限制,无法退出登录”
此处限制条件比较多,逐个检查
- 儿童设备:设置-屏幕使用时间-内容和隐私访问限制-关闭“内容和隐私访问限制”
- 家长设备:关闭儿童账号-屏幕使用时间(见上4.关闭-屏幕使用时间)
- 儿童设备:设置-屏幕使用时间-内容和隐私访问限制-查看描述文件(如果以下不能解决,尝试删除设备的描述文件)
WKWebView适配
- 去除ErrorView的遮挡
- 定义错误码
// error code
**static** **var** webKitErrorDomainCode = 105
**static** **var** webKitErrorDomain = "WebKitErrorDomain"
- url加载和跳转回调
private func onWebViewLoadFinish(success: Bool, error: NSError?) {
if success {
hideLoadingView()
} else if Self.checkIsAccessRestrictedError(error: error) {
// 展示出 允许 用户设置配额
hideLoadingView()
// wakeupAccessAuthWebController 展示域名对应的“访问限制”授权页
if !isAccessRestrictedIgnore && wakeupAccessAuthWebController(by: self) {
return
}
} else {
showErrorView()
}
}
// 检查是否为,访问限制错误
static func checkIsAccessRestrictedError(error: NSError?) -> Bool {
guard let error = error else {
return false
}
return error.domain == Self.webKitErrorDomain && error.code == Self.webKitErrorDomainCode
}
- 解决二次present不能弹出问题
private func wakeupAccessAuthWebController(by webView: JDWebView) -> Bool {
guard !webView.isAccessRestrictedIgnore else {
// 跳转来的,返回,断开循环调用
return false
}
guard !isCheckingAccess else {
// 仅有一个在授权
return false
}
// 找到webview对应的controller
guard let controller = webView.findViewController() else {
return false
}
let urlString = webView.currentUrl ?? ""
// 找到controller唤起的present controller
if let topController = controller.topPresentingViewController() {
// 二次弹出
// 1.topPresentController dismiss
isCheckingAccess = true
topController.dismiss(animated: true) {
// 2. 跳转到新的 授权页
let accessAuthWebController = AccessAuthWebViewController.createBy(url: urlString)
let rootShowController = UIApplication.getTopViewController(master: false)
rootShowController?.showDetailViewController(accessAuthWebController, sender: nil)
}
} else {
// 没有presentingViewController, 不是二次弹出,无需处理
return false
}
return true
}
private extension UIView {
/// 返回承载当前视图的 UIViewController
func findViewController() -> UIViewController? {
var nextResponder: UIResponder? = self
while nextResponder != nil {
nextResponder = nextResponder?.next
if let viewController = nextResponder as? UIViewController {
return viewController
}
}
return nil
}
}
private extension UIViewController {
func topPresentingViewController() -> UIViewController? {
var topVC = presentingViewController
while let parent = topVC?.presentingViewController {
topVC = parent
}
return topVC
}
}
展望
结合福格行为模型,设计儿童(14-)学习奖惩制度