Screen Time API를 사용한 셀프 컨트롤 앱을 만들려고 하면 처음에 3개의 프레임워크가 등장한다. FamilyControls, ManagedSettings, 그리고 ManagedSettingsUI 이다. iOS 개발이 처음이라면 프레임워크의 역할 분담이 이해하기 어렵고, 어느 것을 import 하면 좋을까 헤매는다. 각각의 책무를 먼저 파악해 두면, 나중에 설계가 무너지기 어렵다.
우선 권한 부여: AuthorizationCenter
앱이 Screen Time API를 사용하여 제한을 적용하려면 사용자의 권한이 필요합니다. 진입 점은 AuthorizationCenter.shared.requestAuthorization(for:)이고 AuthorizationCenter는 FamilyControls 프레임 워크에 속합니다.
인가의 종류는 2개 있다. 자녀의 단말을 보호자가 제어하는 individual 와 자신의 단말을 스스로 제어하는 selfRestriction 이다. 셀프 컨트롤 계 앱에서는 후자를 사용한다. iOS 개발에 익숙하지 않으면 「허가」와 「퍼미션(위치정보등의 허가)」이 혼동하기 쉽지만, 여기서 말하는 인가는 Screen Time 기능 전체를 사용하는 권한의 취득으로, 한 번 취하면 이후는 유지된다.
앱 기동마다 요구하는 것이 아니라, 최초 기동 플로우 중에서 한 번만 부르는 설계로 한다.
차단 대상 선택: FamilyActivityPicker
차단하려는 웹사이트와 카테고리를 선택하는 UI는 Apple이 FamilyActivityPicker로 제공합니다. 이것은 SwiftUI 의 시트로서 표시한다.
여기서 iOS 미경험자가 잘 막히는 것은 선택 결과를 자유 텍스트 URL이나 도메인 이름으로 꺼낼 수 없다는 것이다. FamilyActivitySelection라는 모델에 싸인 토큰으로 돌아온다. 이 토큰은 Codable을 준수하므로 JSON이나 파일에 저장할 수 있지만 내용의 URL 문자열을 직접 읽을 수는 없습니다.
「스스로 도메인의 리스트를 관리하고 싶다」라고 하는 발상으로 설계하면, 여기에서 막힌다. FamilyActivityPicker 가 돌려주는 FamilyActivitySelection 를 그대로 사용하는 설계가 전제다. 웹 개발 경험이 있으면 도메인을 문자열로 취급하고 싶어지지만, iOS의 Screen Time API는 그 설계를 취하지 않는다.
규칙 적용: ManagedSettings
사용자가 한 선택을 실제 제한으로 적용하는 것이 ManagedSettings의 역할이다. ManagedSettingsStore에 대한 규칙을 씁니다.
let store = ManagedSettingsStore()store.shield.webDomains = selection.webDomainsstore.shield.applicationCategories = .specific(selection.categories)shield.webDomains에 FamilyActivitySelection에서 꺼낸 토큰을 전달하면 해당 웹 사이트에 액세스 할 때 실드 화면이 표시됩니다. 「실드」는 Apple의 Screen Time이 준비한 블록 화면으로, Safari 위에 겹쳐 표시된다.
규칙은 store.clearAllSettings()로 완전히 취소 할 수 있습니다. 잠금 해제 처리의 구현에서는 이 호출이 중심이 된다.
디자인의 골격
3개를 조합하면 기본적인 흐름은 이렇게 된다.
시작시 AuthorizationCenter에서 허가를 확인하고, 비인가이면 요청을 발행합니다. 설정 화면에서 FamilyActivityPicker를 표시하고 사용자 선택을 FamilyActivitySelection로 App Group의 공유 컨테이너에 저장합니다. 포커스 모드 시작시 ManagedSettingsStore에 규칙을 쓰고 종료시 clearAllSettings()로 해제합니다.
프리텍스트의 도메인 관리와 비교해 유저의 선택사항이 한정되는 것처럼 보이지만, 이것이 이 플랫폼의 사양이다. 유지보수나 오등록 걱정 없이 Apple의 카테고리 분류를 그대로 활용할 수 있다. iOS에 익숙해지면 “Apple의 준비한 테두리를 타다”라는 판단이 자연스러워진다.
구현의 복잡성은 실드 화면의 커스터마이즈와 실드에서 앱으로의 잠금 해제 연계에 집중하게 된다.
hsb.horse