IOS开发基于FamilyControls功能程序

2,480 阅读1分钟

苹果在WWDC21发布了iOS15,引入了FamilyControls框架,帮助开发者实现家长控制和屏幕使用时间管理功能。

但是在iOS15系统请求权限的时候,会返回失败,错误描述是:Family Controls is only available for child and teen iCloud accounts

查询资料发现,在WWDC21的视频中提到,为防止滥用 只有儿童账户才能使用Family Controls功能,而在iOS16中放宽了该权限,成人账户同样可以使用Family Controls,而且要使用异步Api。

前提条件

  1. 一个有效的Apple开发者账户

  2. Xcode 13或者更高的版本

  3. 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太久了,那就来背一首古诗吧

欢迎同学们一起交流讨论,我是無涯~