Most phone limit tools make the same trade: either you can override the limit alone, or someone else gets too much visibility. PactBuddy is trying to sit in the narrower middle. A buddy should know whether the pact held. They do not need a diary of every app you opened.
A screen time accountability app needs a narrow proof path
The first product choice is who picks the boundary. In PactBuddy, the person making the goal chooses the apps, categories, or web domains and sets the daily minute limit. The buddy is not browsing a dashboard and deciding what counts as bad behavior.
The app then asks Apple for individual Family Controls authorization and starts a daily Device Activity monitor. The empty selection guard matters because a vague "use my phone less" goal is too easy to argue with later.
try await AuthorizationCenter.shared.requestAuthorization(for: .individual)
guard !selection.applicationTokens.isEmpty || !selection.categoryTokens.isEmpty || !selection.webDomainTokens.isEmpty else {
throw ScreenTimeError.emptySelection
}
if let data = try? PropertyListEncoder().encode(selection) { AppGroupStore()?.setFamilySelectionData(data) }
AppGroupStore()?.setScreenTimeLimit(limitMinutes)That selection is stored in the shared App Group for the app and its Screen Time extensions. It is not a buddy facing list. Apple documents the permission model behind this through the Family Controls framework.
The buddy gets a result, not a usage diary
The useful proof is small: did today pass, fail, or stay unknown? PactBuddy stores that status with a bucketed minute estimate. The shared model has no place for exact per app usage.
public struct ScreenTimeResult: Codable, Equatable, Sendable {
public let status: ScreenTimeStatus
/// Bucketed estimate of minutes spent (rounded to a coarse bucket by the writer).
public let estimateMinutes: Int
}The report extension rounds the activity total to a 15 minute bucket before it writes the result. That is less satisfying than a perfect chart. Good. A screen time accountability app should resist the urge to become surveillance just because the operating system can measure more.
let exactMinutes = Int(duration / 60)
let roundedMinutes = Int((Double(exactMinutes) / 15.0).rounded() * 15.0)
let status: AppGroupStore.ScreenTimeStatus = exactMinutes <= limit ? .pass : .fail
AppGroupStore()?.setResult(.init(status: status, estimateMinutes: roundedMinutes), for: .now)
return "About \(roundedMinutes) minutes · \(status.rawValue)"A daily threshold is easier to agree on than a live feed
PactBuddy monitors the selected activity from midnight to 23:59 and uses one event threshold for the budget. When the event fires, the monitor writes a failed result with a rounded estimate. If the day ends before the threshold fires, it writes a passing result.
let schedule = DeviceActivitySchedule(
intervalStart: DateComponents(hour: 0, minute: 0),
intervalEnd: DateComponents(hour: 23, minute: 59),
repeats: true
)
let event = DeviceActivityEvent(
applications: selection.applicationTokens,
categories: selection.categoryTokens,
webDomains: selection.webDomainTokens,
threshold: DateComponents(minute: limitMinutes)
)
try DeviceActivityCenter().startMonitoring(activity, during: schedule, events: [budgetEvent: event])This is a blunt contract, but it is legible. "Stay under 45 minutes of TikTok today" gives both people a cleaner agreement than "be less online." It also avoids a live feed that makes the buddy responsible for policing every moment.
The accountability happens after the result
The Screen Time result is only one kind of proof in PactBuddy. The app also supports wake up selfies and workout photos. What makes the system different is the handoff after a miss: the owner submits proof, and the buddy confirms, rejects, or uses a weekly vouch.
That is the same loop described in the broader post on what an accountability partner app needs to do after you miss. Screen Time is just the proof type where the privacy boundary is easiest to get wrong.
What this does not solve
This is not a total phone lock. It does not stop someone from changing their mind, deleting an app, or choosing a weak goal. PactBuddy also still depends on Apple's Screen Time entitlement path, which has to be approved before a production app can distribute this feature.
Those limits are part of the point. If a screen time accountability app needs to watch everything to work, the pact is already in trouble. The better test is smaller: can one trusted person verify one agreed limit without learning more than they need to know?
Start with the app you keep reopening
Pick the app or category that keeps swallowing the day. Set a number you would not be embarrassed to defend. Then choose the person whose quiet "did you keep it?" would actually change your behavior.