苹果在WWDC21发布了iOS15,引入了FamilyControls
框架,帮助开发者实现家长控制和屏幕使用时间管理功能。
但是在iOS15系统请求权限的时候,会返回失败,错误描述是:Family Controls is only available for child and teen iCloud accounts
查询资料发现,在WWDC21的视频中提到,为防止滥用 只有儿童账户才能使用Family Controls功能,而在iOS16中放宽了该权限,成人账户同样可以使用Family Controls,而且要使用异步Api。
前提条件
-
一个有效的Apple开发者账户
-
Xcode 13或者更高的版本
-
IOS版本16或以上(现在都18了哦)
项目配置
FamilyControls
框架主要是为Swift语言设计的,所以如果你的项目是Swift语言编写的,那么恭喜你可以很方便的使用这两个框架提供的所有接口。
如果是Objective-C语言,那也没关系,可以使用桥接头文件在Objective-C里面调用Swift方法。
添加FamilyContorls
能力:
注意注意注意:只有苹果开发者账户才有这个功能,不是开发者账户没有这个选项
请求用户授权
在AppDelegate
里面请求授权:
import SwiftUI
import FamilyControls
class AppDelegate: NSObject, UIApplicationDelegate {
// Make this request when the app launches
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
// 这个是ios15的api,在ios16里面被弃用了
//AuthorizationCenter.shared.requestAuthorization { result in
// The request can either result in success or failure
//switch result {
//case .success():
//break
//case .failure(let error):
//print("Error for Family Controls: \(error.localizedDescription)")
//}
//}
Task {
do {
try await AuthorizationCenter.shared.requestAuthorization(for: .individual)
} catch {
print("Failed to enroll Aniyah with error: \(error)")
}
}
return true
}
}
当app启动的时候就会弹出请求访问屏幕时间限制的弹窗:
添加familyActivityPicker选择:
VStack {
Button("Select Apps to Discourage") {
isDiscouragedPresented = true
}
.familyActivityPicker(isPresented: $isDiscouragedPresented, selection: $model.selectionToDiscourage)
Button("Select Apps to Encourage") {
isEncouragedPresented = true
}
.familyActivityPicker(isPresented: $isEncouragedPresented, selection: $model.selectionToEncourage)
}
.onChange(of: model.selectionToDiscourage) { newSelection in
MyModel.shared.setShieldRestrictions()
}
锁定App:
// OnChange的时候就会调用MyModel的这个方法来锁定App
func setShieldRestrictions() {
// Pull the selection out of the app's model and configure the application shield restriction accordingly
let applications = MyModel.shared.selectionToDiscourage
// 选择了单个应用程序的时候就会返回 applications.applicationTokens,设置为这个就会锁定选中的app;设置为nil就会取消锁定
store.shield.applications = applications.applicationTokens.isEmpty ? nil : applications.applicationTokens // 选择了一个分类的时候就会返回 applications.categoryTokens,设置为这个就会锁定选中的分类里面的这些app;设置为nil就会取消锁定
store.shield.applicationCategories = applications.categoryTokens.isEmpty
? nil
: ShieldSettings.ActivityCategoryPolicy.specific(applications.categoryTokens)
}
获取屏幕使用时间:
获取屏幕使用时间需要添加一个DeviceActivityReportExtension
Target
Xcode会自动创建这个模版Target:
自定义锁定App页面:
想象一下我把别人app锁住,然后运行我的程序 这似乎好像有点似曾相识的感觉。en... 对 这是病毒啊!自然是不会被苹果允许的
自定义锁定App界面需要添加一个shield configuration的target:
xcode会自动创建一个shield configuration模板:
shieldConfigurationExtension就是自定义界面的代码,能够自定义的就是背景模糊样式、背景颜色、icon、标题等,我能想到的是刷app太久了,那就来背一首古诗吧
欢迎同学们一起交流讨论,我是無涯~