前提: 看文章之前,你需要初步了解swiftUI,screenTime是使用swiftUI才能开发的
目的:本篇文章的目的是记录下从0到1创建一个Screen Time Control类型项目
主要涉及的框架:FamilyControls,DeviceActivity,ManagedSettings,ManagedSettingsUI,可以去官网先查看文档
1. 首先创建一个swiftUI的项目
image.png
2. 获取FamilyControl权限
首先添加FamilyControl的权限,如果不将其添加为功能,则无法看到请求权限的弹出窗口
image.png
添加 Capability
后,我们可以在想要显示并请求权限的任何应用屏幕上运行以下代码块。在这里,我们选择请求类型为individual
,这意味着我们希望为我们的设备获取此权限,但如果有家庭共享帐户,也可以为请求此权限child
,代码如下:
import SwiftUI
import FamilyControls
struct ContentView: View {
var body: some View {
VStack {
Button {
Task {
do {
try await AuthorizationCenter.shared.requestAuthorization(for: .individual)
} catch {
print("Failed to enroll Aniyah with error: \(error)")
}
}
} label: {
Text("获取screenTime屏幕权限")
}
}
.padding()
}
}
如果想撤销权限,可以运行下面的代码块:
AuthorizationCenter .shared.revokeAuthorization {
}
可以通过该属性访问当前授权状态authorizationStatus
let currentStatus = AuthorizationCenter.shared.authorizationStatus
这时候,我们运行app,就可以初步获取到权限了:
image.png
3. FamilyActivitySelection 选择app
接下来可以弹出app选择器界面,选择想要屏蔽的app进行屏蔽
import SwiftUI
import FamilyControls
struct ContentView: View {
@State var isPresented = false
@State var screenTimeSelection = FamilyActivitySelection ()
var body: some View {
VStack(spacing: 50) {
Button {
Task {
do {
try await AuthorizationCenter.shared.requestAuthorization(for: .individual)
} catch {
print("Failed to enroll Aniyah with error: \(error)")
}
}
} label: {
Text("获取screenTime屏幕权限")
}
Button {
isPresented = true
} label: {
Text("选择app界面")
}
}
.padding()
.familyActivityPicker(isPresented: $isPresented, selection: $screenTimeSelection)
}
}
image.png
4. 屏蔽app
接下来采用ManagedSettings
框架进行屏蔽app,在上一步上方中已经进行了screenTimeSelection
选择了指定的app,这一步就是对指定的app进行屏蔽
import ManagedSettings
private let store = ManagedSettingsStore()
func blockApp() {
let applications = screenTimeSelection.applicationTokens
let categories = screenTimeSelection.categoryTokens
if !applications.isEmpty {
print("applications: \(applications)")
}
if !categories.isEmpty {
print("categories: \(categories)")
}
// 屏蔽应用
store.shield.applications = applications.isEmpty ? nil : applications
store.shield.applicationCategories = categories.isEmpty ? nil : .specific(categories)
store.shield.webDomainCategories = categories.isEmpty ? nil : .specific(categories)
}
整个代码就是如下:
import SwiftUI
import FamilyControls
import ManagedSettings
struct ContentView: View {
@State var isPresented = false
@State var screenTimeSelection = FamilyActivitySelection ()
private let store = ManagedSettingsStore()
var body: some View {
VStack(spacing: 50) {
Button {
Task {
do {
try await AuthorizationCenter.shared.requestAuthorization(for: .individual)
} catch {
print("Failed to enroll Aniyah with error: \(error)")
}
}
} label: {
Text("获取screenTime屏幕权限")
}
Button {
isPresented = true
} label: {
Text("选择app界面")
}
Button {
blockApp()
} label: {
Text("屏蔽app")
}
}
.padding()
.familyActivityPicker(isPresented: $isPresented, selection: $screenTimeSelection)
}
func blockApp() {
let applications = screenTimeSelection.applicationTokens
let categories = screenTimeSelection.categoryTokens
if !applications.isEmpty {
print("applications: \(applications)")
}
if !categories.isEmpty {
print("categories: \(categories)")
}
// 屏蔽应用
store.shield.applications = applications.isEmpty ? nil : applications
store.shield.applicationCategories = categories.isEmpty ? nil : .specific(categories)
store.shield.webDomainCategories = categories.isEmpty ? nil : .specific(categories)
}
}
这时候打开被屏蔽的app就会显示下面的界面
image.png
5. 解除被屏蔽的app
func stopBlockApp() {
store.shield.applications = nil
store.shield.applicationCategories = nil
store.shield.webDomains = nil
}
整套流程代码如下:
import SwiftUI
import FamilyControls
import ManagedSettings
struct ContentView: View {
@State var isPresented = false
@State var screenTimeSelection = FamilyActivitySelection ()
private let store = ManagedSettingsStore()
var body: some View {
VStack(spacing: 50) {
Button {
Task {
do {
try await AuthorizationCenter.shared.requestAuthorization(for: .individual)
} catch {
print("Failed to enroll Aniyah with error: \(error)")
}
}
} label: {
Text("获取screenTime屏幕权限")
}
Button {
isPresented = true
} label: {
Text("选择app界面")
}
Button {
blockApp()
} label: {
Text("屏蔽app")
}
Button {
stopBlockApp()
} label: {
Text("解除app")
}
}
.padding()
.familyActivityPicker(isPresented: $isPresented, selection: $screenTimeSelection)
}
func blockApp() {
let applications = screenTimeSelection.applicationTokens
let categories = screenTimeSelection.categoryTokens
if !applications.isEmpty {
print("applications: \(applications)")
}
if !categories.isEmpty {
print("categories: \(categories)")
}
// 屏蔽应用
store.shield.applications = applications.isEmpty ? nil : applications
store.shield.applicationCategories = categories.isEmpty ? nil : .specific(categories)
store.shield.webDomainCategories = categories.isEmpty ? nil : .specific(categories)
}
func stopBlockApp() {
store.shield.applications = nil
store.shield.applicationCategories = nil
store.shield.webDomains = nil
}
}
接下来,我们将去学习进阶,通过指定时间内去block指定的app