본문 바로가기

IOS Swift

Screen Time API (1) - WWDC2021

ScreenTime API로 제한된 네이버 App

안녕하세요. Hong입니다. 🐶

WWDC21의 Meet ther Screen Time 영상 보면서

나의 앱에서 다른 앱의 사용 시간제한을 설정할 수 있다길래

신기해서 바로 구현해 봤습니다.


목차

  1. WWDC 영상으로 Screen Time API 학습하기
  2. Screen Time API 사용해 보기

 

1. WWDC 영상으로 Screen Time API 학습하기

 

Screen Time API에서 할 수 있는 기능

  1. 사용자와 가족이 앱과 웹 사이트를 얼마나 자주 사용하는지 추적 가능
  2. 사용 제한을 설정하여 시간 관리 가능
  3. 가족 구성원과 사용량을 공유하여 디바이스를 어떻게 사용하고 있는지 확인 가능
  4. 자녀가 누구와 소통하는지 관리 가능

 

사용 환경

  • iOS 15
  • iPadOS 15
  • 100% Swift, SwiftUI 코드로 이루어짐

 

세 가지 기본 원칙

  1. 기존 제한에 대한 직접 API 액세스를 위한 최신 온디바이스 프레임워크 제공 (네트워크 연결 없이 사용 가능)
  2. 사용자 개인 정보 보호 (애플 포함 그 누구도(가족 구성원이라 할지라도) 어떤 웹사이트를 방문했는지, 무슨 앱을 사용하는지 까지는 알 수 없음)
  3. 개발자가 다양하게 자녀 보호 환경을 만들 수 있도록 보장하는 것

Apple은 이러한 세 가지 원칙을 가지고 Screen Time API를 설계했고, 아래의 3가지 프레임 워크를 만들었습니다.

 

세 가지 프레임워크

 

1️⃣ Managed Settings 

iOS 설정에 있는 스크린 타임과 같이 앱에 직접적인 제한을 줄 수 있는 프레임워크

iOS 설정에서 마찬가지로, 계정 잠금, 비밀번호 변경 방지, 웹 트래픽 필터링, 애플리케이션 보호 등 다양한 제한 사항을 설정할 수 있습니다.

2️⃣ Family Controls

개인 정보 보호 정책을 주도하는 프레임워크

가족 공유를 활용하면 가족 제어는 보호자 승인 없이 Screen Time API에 액세스 하는 것을 방지합니다. 보호자의 승인을 받은 앱은 보호자의 승인 없이는 기기에서 제거될 수 없습니다. 또한 Family Controls는 앱과 웹사이트를 나타내는 불투명 토큰을 제공합니다. 불투명 토큰은 Screen Time API 전체에서 사용을 모니터링하거나 제한하고 가족 공유 그룹 외부의 누구도 어떤 앱과 웹 사이트가 사용되고 있는지 알 수 없도록 하는데 사용됩니다.

3️⃣ Device Activity

앱을 실행하지 않고도 코드를 돌릴 수 있게 해주는 기능을 제공하여 앱에서 스크린 타임 사용할 수 있게 해주는 프레임워크

앱 및 웹 사용을 모니터링하고 필요할 때 코드를 실행할 수 있는 새로운 방법을 제공하여 스크린 타임 이상의 기능을 제공할 수 있습니다. 자녀 보호 앱은 부모를 위한 앱이므로 자녀가 자녀 보호 앱을 실행할 이유가 거의 없습니다. 그렇다면 제한을 설정하기 위해 코드를 어떻게 실행할까요? 정답은 바로 Device Activity schedules 및 event입니다.

Device Activity schedules은 시간 범위의 시작과 끝에서 앱의 확장을 호출합니다. 말이 좀 어려운데 예를 들면 (10시 ~ 12시) 이런 시간 범위가 있다면 10시와 12시에 앱의 확장이란 곳에 적혀 있는 코드가 호출된다고 이해하시면 쉽습니다.

Device Activity event는 사용자의 디바이스가 사용 임계점에 도달했을 때 앱의 확장을 호출하는 사용 모니터입니다. 예를 들면 어떤 앱에 사용 제한을 5분 걸어놓으면 그 앱을 5분 모두 사용하면 앱의 확장이란 곳에 적혀 있는 코드가 호출됩니다.

 


2. Screen Time API 사용해 보기

 

1. 스크린 타임 권한 여부 묻기 

타겟 -> Capability -> Family Controls 추가

Family Controls를 추가 후 apple에서 스크린타임 권한 허용을 묻는 팝업 코드를 추가해 주시면 됩니다.

import SwiftUI
import FamilyControls

@main
struct AppLockerApp: App {

    let center = AuthorizationCenter.shared
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    Task {
                        do {
                            try await center.requestAuthorization(for: .individual)
                        } catch {
                            print("Fail: \(error)")
                        }
                    }
                }
        }
    }
}

 

 

코드도 추가했으니 실행 한번 해봅시다.


 

잘 되네요. 👍

 

2. 제한 걸 앱 목록 보기

 

import SwiftUI
import FamilyControls

struct ContentView: View {
    
    @State var selection = FamilyActivitySelection()
    @State var isPresented = false
    
    var body: some View {
        
        VStack {
            Button {
                isPresented = true
                
            } label: {
                Text("앱 목록 보기")
            }
        }
        .familyActivityPicker(isPresented: $isPresented, selection: $selection)
    }
}

#Preview {
    ContentView()
}

 

3. 앱 사용 제한 걸기

제한 걸 목록에서 앱을 골랐으면 이제 제한을 걸어야겠죠? 담당할 Model을 만듭시다.

import Foundation
import FamilyControls
import ManagedSettings // WWDC에서 직접적인 사용 제한을 걸기 위한 프레임워크라고 소개했는데 그 말대로네요.

class Model: ObservableObject {
    
    static var shared = Model()
    
    let store = ManagedSettingsStore()
    @Published var selectionToDiscourage: FamilyActivitySelection
    
    init() {
        selectionToDiscourage = FamilyActivitySelection()
    }
    
    func setShieldRestrictions() {
        let applications = Model.shared.selectionToDiscourage
        
        store.shield.applications = applications.applicationTokens.isEmpty ? nil : applications.applicationTokens
        store.shield.applicationCategories = applications.categoryTokens.isEmpty
        ? nil
        : ShieldSettings.ActivityCategoryPolicy.specific(applications.categoryTokens)
    }
}

 

Model을 만들었으니 Model을 사용하도록 View쪽도 변경해 줍시다.

import SwiftUI
import FamilyControls

@main
struct AppLockerApp: App {

    @StateObject var model = Model.shared
    let center = AuthorizationCenter.shared
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(model)
                .onAppear {
                    Task {
                        do {
                            try await center.requestAuthorization(for: .individual)
                        } catch {
                            print("Failed to enroll Aniyah with error: \(error)")
                        }
                    }
                }
        }
    }
}
import SwiftUI
import FamilyControls

struct ContentView: View {
 
    @EnvironmentObject var model: Model
    
    @State var isPresented = false
    
    var body: some View {
        
        VStack {
            Button {
                isPresented = true
                
            } label: {
                Text("앱 목록 보기")
            }
            .familyActivityPicker(isPresented: $isPresented, selection: $model.selectionToDiscourage)
        }
        .onChange(of: model.selectionToDiscourage, {
            Model.shared.setShieldRestrictions()
        })
    }
}

#Preview {
    ContentView()
}

 

완료..!!

완성

 

이렇게 세 가지 프레임워크 중 Managed Settings, Family Controls를 사용해 봤습니다.

나머지 한 개인 Device Activity는 사용하려면 앱과 앱의 확장에서 데이터를 서로 공유하는 영역을 만들어야 해서

이번 글이 엄청 길어질 것 같아서 WWDC2022 Screen Time API 관련 영상 정리할 때 같이 작성하겠습니다. ㅎㅎ


참고

- Screen Time API 사용해 보기 전체 코드: https://github.com/HongzCloud/AppLocker

반응형