Skip to main content

Components

<ActivityPicker />

Native view for selecting apps, categories, and web domains. The selection is stored natively under the selectionId you provide — JS receives only counts and opaque token handles.

import { ActivityPicker, type OnSelectionChangeEvent } from 'expo-screen-time';

function AppPicker() {
return (
<ActivityPicker
style={{ flex: 1 }}
selectionId="my-blocklist"
headerText="Select apps to block"
footerText="Selected apps will be blocked"
onSelectionChange={(event) => {
const { metadata, tokens } = event.nativeEvent;
console.log(`${metadata.applicationCount} apps, ${tokens.length} tokens`);
}}
onOpen={() => console.log('Picker opened')}
onClose={() => console.log('Picker closed')}
/>
);
}

Props:

PropTypeDescription
selectionIdstring (required)ID of the selection in the native store
styleStyleProp<ViewStyle>Container style
headerTextstringHeader text displayed in the picker
footerTextstringFooter text displayed in the picker
onSelectionChange(event: { nativeEvent: OnSelectionChangeEvent }) => voidnativeEvent = { metadata: SelectionMetadata, tokens: TokenHandle[] }
onOpen() => voidCalled when the picker view appears
onClose() => voidCalled when the picker view disappears

After picking, use the same selectionId with blockSelection or startMonitoring, and manage it with the selection utilities.

<DeviceActivityReport />

:::info Requires the DeviceActivityReportExtension target :::

Display usage analytics from iOS Screen Time. The data renders inside a sandboxed extension and never reaches JavaScript; styling is passed through via the App Group. Renders a styled fallback on non-iOS platforms.

import { DeviceActivityReport } from 'expo-screen-time';

<DeviceActivityReport
context="TotalActivity"
filterSegment="daily"
filterDate={new Date()}
style={{ height: 300 }}
accentColor="#FF6B00"
backgroundColor="#1a1a1a"
textColor="#ffffff"
showPickups={true}
showTopApps={true}
showChart={true}
chartStyle="bar"
/>

Props:

PropTypeDefaultDescription
context'TotalActivity' | 'AppList' | 'HourlyChart''TotalActivity'Report view type
filterSegment'daily' | 'weekly''daily'Time filter
filterDateDateTodayDate to show the report for
styleStyleProp<ViewStyle>-Container style
accentColorstring-Accent color (hex)
backgroundColorstring-Background color (hex)
textColorstring-Text color (hex)
showPickupsboolean-Show pickup count
showTopAppsboolean-Show top apps section
showChartboolean-Show usage chart
chartStyle'bar' | 'pie'-Chart visualization style

Token Labels

Render an app/category/domain name and icon from an opaque token handle. Due to Apple's privacy design, token names can't be read programmatically — they can only be rendered natively. Get handles from getTokens(selectionId) or the picker's onSelectionChange.

import { getTokens, ApplicationLabel, CategoryLabel, WebDomainLabel } from 'expo-screen-time';

const tokens = await getTokens('my-blocklist');
const apps = tokens?.filter((t) => t.type === 'application') ?? [];

// Display an app's name and icon
<ApplicationLabel
selectionId="my-blocklist"
handle={apps[0].handle}
displayMode="title-and-icon"
style={{ height: 40 }}
/>

CategoryLabel and WebDomainLabel work the same way for type: 'category' and type: 'webDomain' handles. The generic TokenLabel takes an explicit tokenType prop instead:

<TokenLabel
selectionId="my-blocklist"
handle={handle}
tokenType="application"
displayMode="icon-only"
/>

Props (all labels):

PropTypeDescription
selectionIdstringSelection containing the token
handlestringOpaque token handle
displayMode'icon-only' | 'title-only' | 'title-and-icon'Default 'title-and-icon'
styleStyleProp<ViewStyle>Container style
tokenType'application' | 'category' | 'webDomain'TokenLabel only