スクリーンタイム関連APIの制限
スクリーンタイム領域のアプリで必須のDeviceActivityとManagedSettingsStoreのAPIには制限が多く、しかもドキュメントではあまりハッキリと言及されていない制限もあります。ここではその制限と挙動をリストアップしていきます。
DeviceActivitySchedueの最大登録可能件数は20件
DeviceActivityCenterやDeviceActivityScheduleには記述がないのですが、DeviceActivityCenter.MonitoringError.excessiveActivitiesにて20件より多く登録しようとするとエラーを投げると言及があります。
The maximum number of activities that can be monitored at one time by an app and its extensions is twenty.
(Apple Inc, https://developer.apple.com/documentation/deviceactivity/deviceactivitycenter/monitoringerror/excessiveactivities#discussion)
筆者の開発したAppStopsでは1オブジェクトごとに独立した時間帯と上限のスケジュールを提供するため2つのDeviceActivityScheduleを使うので、最大オブジェクト登録件数を10件としています。
DeviceActivitySchedueの最小と最大インターバル
ManagedSettingsStore.ShiledSettingsのトークン設定可能数は50件
例えばapplicationsの説明を読むと50件まで設定可能であることが分かります。
Your app can shield up to 50 application tokens at once.
(Apple Inc, https://developer.apple.com/documentation/managedsettings/shieldsettings/applications-swift.property)
これはwebDomains, applicationCategories, webDomainCategoriesも同様です。
カテゴリの指定の場合は、.specific(_:except:)
だと最初のパラメーターで渡すSet<ActivityCategoryToken>
もexceptで渡すSet<Token<Activity>>
もどちらも50件まで、.all(except:)
だとSet<Token<Activity>>
が50件までです。
このAPIの注意は、DeviceActivityCenter
などと違って、設定時にエラーを投げないことです。
制限を超えた時にどのような挙動をするのか分からないうえ気づきにくいので、注意しないとバグを作り込んでしまいます。
ManagedSettingsStore(named:)の最大件数は50件
Whats New in Screen Time API - WWDC22内でしか言及されていないのですが、ManagedSettingsStore(named:)には件数制限があり、50件までしかユニークなストアを扱えません。
DeviceActivityEventのAPIがShieldSettingsと噛み合わない
DeviceActivityEventにトークンと閾値(threshold)を登録することで、DeviceActivityMonitorのeventDidReachThreshold(_:activity:)が呼ばれるので、タイムリミットに従ってアプリを制限する機能を作ることができます。
しかし、アプリを制限するときに使うシールドのAPIが、ShieldSettings.ActivityCategoryPolicy.specific(_:except:) というブラックリスト形式と、.all(except:)というホワイトリスト形式をどちらも指定できるのに対して、DeviceActivityEventは時間計測をするアプリ、webドメイン、カテゴリを渡すことしかできず、ホワイトリスト形式での指定が行えません。
これにより、タイムリミット機能とホワイトリストでの制限対象選択は、1度にどちらか一方のみしかユーザーに提供できません。AppStopsでは仕方ないので、「除外の選択オプションが選択されている場合は上限の機能が使えません。」というような表記を行い、利用時のオプションによって使えない機能が出てしまうことを許容しています。
DeviceActivityCenter.startMonitoring(_:during:events:)の挙動
DeviceActivityCenter.startMonitoring(_:during:events:)は、同じDeviceActivityNameを渡すと上書きを行い、現在時刻がスケジュール時間の場合はDeviceActivityMonitor の各ハンドラが即時呼び出されますが、既存のDeviceActivityScheduleと全く値が変わらないスケジュールのモニタリングを開始した場合は、ハンドラの呼び出しがスキップされます。 これはLoggerを仕込んでコンソールアプリを開きながら検証した結果判明しました。
シンプルな実装をしているうちは問題になりませんが、込み入ったことをすると知らず知らずの内に発生している可能性があります。注意してください。
毎回確実に実行してもらう必要がある場合は、一度停止してから再度スタートの処理をすると良いかもしれません。
おわりに
かなりAPIも制限が多い領域なので、利用する際はしっかりと下調べ・リサーチをしてから利用しましょう。また何か新しい制限を発見した場合は随時更新していきます。
紹介
記事内の制限をうまく抑えつつ筆者が開発したAppStopsというスクリーンタイム制限アプリがあります。よければ実際に動かしながらどのように制限のハンドリングしているかチェックしてみてください。
Discussion