logo hsb.horse
← Back to blog index

Blog

Design self-limiting blocks for iOS with FamilyControls + ManagedSettings

How the three elements of AuthorizationCenter, FamilyActivityPicker, and ManagedSettings are combined. We have organized the reasons why a token-based design should be used instead of free text domain input and the framework of its implementation.

Published:

When trying to create a self-control app using the Screen Time API, three frameworks first appear. They are FamilyControls, ManagedSettings, and ManagedSettingsUI. If you are new to iOS development, it may be difficult to understand the roles of frameworks, and you may be confused as to which one to import. Understanding each person’s responsibilities first will prevent the design from collapsing later.

Get permission first: AuthorizationCenter

Apps need permission from the user to use the Screen Time API to enforce limits. The entry point is AuthorizationCenter.shared.requestAuthorization(for:), and AuthorizationCenter belongs to the FamilyControls framework.

There are two types of authorization. individual allows parents to control their children’s devices, and selfRestriction allows parents to control their own devices. Use the latter for self-control apps. If you are not familiar with iOS development, it is easy to confuse “authorization” and “permission (permission for location information, etc.),” ​​but the authorization here refers to the acquisition of authority to use the entire Screen Time function, and once obtained, it is maintained thereafter.

Rather than requesting it every time the app starts, it is designed to be called only once during the initial startup flow.

Select what to block: FamilyActivityPicker

Apple provides a UI for selecting the websites and categories you want to block as FamilyActivityPicker. This will be displayed as a SwiftUI sheet.

A common problem here for people new to iOS is that they can’t extract the selection results as free text URLs or domain names. It is returned as a token wrapped in a model called FamilyActivitySelection. This token is Codable compliant, so it can be saved in JSON or a file, but the URL string inside cannot be read directly.

If you design with the idea of ​​“I want to manage the list of domains myself,” you will get stuck here. The premise is that the design uses FamilyActivitySelection returned by FamilyActivityPicker as is. If you have experience with web development, you might want to treat domains as strings, but iOS’s Screen Time API doesn’t take that design.

Apply rules: ManagedSettings

It is the role of ManagedSettings to enforce the actual limits on the choices made by the user. Write rules for ManagedSettingsStore.

let store = ManagedSettingsStore()
store.shield.webDomains = selection.webDomains
store.shield.applicationCategories = .specific(selection.categories)

If you pass the token extracted from FamilyActivitySelection to shield.webDomains, a shield screen will be displayed when accessing the corresponding website. A “shield” is a block screen created by Apple’s Screen Time that overlays Safari.

All rules can be canceled with store.clearAllSettings(). This call is central to the implementation of the unlock process.

Design framework

Combining the three, the basic flow is as follows.

At startup, check authorization with AuthorizationCenter and issue a request if unauthorized. Display FamilyActivityPicker on the settings screen and save the user’s selection as FamilyActivitySelection in the App Group’s shared container. Write rules to ManagedSettingsStore when starting focus mode, and release them with clearAllSettings() when ending focus mode.

It may seem that the user’s options are limited compared to free text domain management, but this is the specification of this platform. There is no need to worry about maintenance or incorrect registration, and you can use Apple’s categorization as is. As you get used to iOS, the decision to “go with the framework provided by Apple” becomes natural.

The complexity of implementation will center on customizing the shield screen and unlocking the shield to the app.