This document provides a step-by-step checklist for implementing the streamlined iOS app.
com.dreamlauncher.lite.iosApp Name: DreamLauncherLite
Use Case: Cross-platform screen time tracking between iOS and macOS devices
Our app helps users track their total device usage across iOS and macOS
by collecting screen time data using Family Controls and syncing it to
a backend server. This allows users to see their complete digital usage
in one place, regardless of which device they're using.
We only collect aggregate screen time duration data, not per-app details.
Data is encrypted and users can delete their data at any time.
cd /Users/ryanheron/Projects/trilogy/DreamLauncher
mkdir dreamlauncher-lite-ios
cd dreamlauncher-lite-ios
git init
# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
*.xccheckout
*.moved-aside
DerivedData/
*.hmap
*.ipa
*.xcuserstate
# CocoaPods
Pods/
# Swift Package Manager
.build/
# Secrets
*.p8
*.mobileprovision
*.cer
Config.xcconfig
DreamLauncherLite/
├── App/
├── Models/
├── Services/
├── ViewModels/
├── Views/
├── Storage/
└── Extensions/
DreamLaunchergit add .
git commit -m "Initial project setup"
git add .
git commit -m "Add storage layer with Keychain and Core Data"
signInWithApple()refreshToken()uploadScreenTime()fetchScreenTime()fetchCombinedScreenTime()# In dreamlauncher-api directory
npm run dev
git add .
git commit -m "Add API client with authentication and screen time endpoints"
git add .
git commit -m "Add authentication with Apple Sign-In"
@main
struct DreamLauncherLiteApp: App {
@StateObject private var authService = AuthService()
var body: some Scene {
WindowGroup {
if authService.isAuthenticated {
DashboardView()
.environmentObject(authService)
} else {
AuthView()
.environmentObject(authService)
}
}
}
}
git add .
git commit -m "Complete auth flow with persistent login"
.notDetermined → Request.denied → Show settings link.approved → Continuegit add .
git commit -m "Add Family Controls authorization"
import DeviceActivity
import SwiftUI
struct TotalActivityReport: DeviceActivityReportScene {
let context: DeviceActivityReport.Context
let content: (ActivityReport) -> TotalActivityView
func makeConfiguration(
representing data: ActivityReport
) -> TotalActivityView {
TotalActivityView(report: data)
}
}
struct TotalActivityView: View {
let report: ActivityReport
var body: some View {
Text("Total: \(report.totalDuration.formatted())")
}
}
git add .
git commit -m "Add DeviceActivityReport extension and data collection"
import DeviceActivity
class DeviceActivityMonitorExtension: DeviceActivityMonitor {
override func intervalDidEnd(for activity: DeviceActivityName) {
super.intervalDidEnd(for: activity)
// Trigger data collection
NSLog("Day ended, collecting screen time data")
}
}
git add .
git commit -m "Add DeviceActivityMonitor for daily tracking"
git add .
git commit -m "Implement dashboard UI with screen time display"
git add .
git commit -m "Add sync service for uploading screen time to API"
import BackgroundTasks
class BackgroundTaskManager {
static let shared = BackgroundTaskManager()
func register() {
BGTaskScheduler.shared.register(
forTaskWithIdentifier: Config.backgroundTaskIdentifier,
using: nil
) { task in
self.handleBackgroundSync(task: task)
}
}
func scheduleSync() {
let request = BGAppRefreshTaskRequest(
identifier: Config.backgroundTaskIdentifier
)
request.earliestBeginDate = Date(
timeIntervalSinceNow: Config.syncInterval
)
try? BGTaskScheduler.shared.submit(request)
}
private func handleBackgroundSync(task: BGTask) {
Task {
await SyncService().syncInBackground()
self.scheduleSync()
task.setTaskCompleted(success: true)
}
}
}
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
BackgroundTaskManager.shared.register()
return true
}
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.dreamlauncher.lite.sync</string>
</array>
# In Xcode debugger console
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.dreamlauncher.lite.sync"]
git add .
git commit -m "Add background sync with BGTaskScheduler"
git add .
git commit -m "Add offline support and retry logic"
OSLog for production logginggit add .
git commit -m "Code cleanup and logging improvements"
git add .
git commit -m "Add cross-platform screen time display"
import SwiftUI
import Charts
struct WeekChartView: View {
let days: [DayData]
var body: some View {
VStack(alignment: .leading) {
Text("This Week")
.font(.headline)
Chart(days) { day in
BarMark(
x: .value("Day", day.date, unit: .day),
y: .value("iOS", day.iosMinutes)
)
.foregroundStyle(.blue)
BarMark(
x: .value("Day", day.date, unit: .day),
y: .value("macOS", day.macosMinutes)
)
.foregroundStyle(.orange)
}
.frame(height: 200)
}
.padding()
.background(Color(.systemBackground))
.cornerRadius(12)
}
}
git add .
git commit -m "Implement week chart with platform breakdown"
struct SettingsView: View {
@EnvironmentObject var authService: AuthService
@Environment(\.dismiss) var dismiss
var body: some View {
List {
Section {
if let user = authService.currentUser {
HStack {
Text("Account")
Spacer()
Text(user.email ?? "Unknown")
.foregroundColor(.secondary)
}
}
}
Section {
Link("Privacy Policy", destination: URL(string: "https://dreamlauncher.app/privacy")!)
Link("Terms of Service", destination: URL(string: "https://dreamlauncher.app/terms")!)
}
Section {
Button("Sign Out", role: .destructive) {
authService.signOut()
dismiss()
}
}
}
.navigationTitle("Settings")
}
}
git add .
git commit -m "Add settings view with logout"
git add .
git commit -m "UI polish and branding"
// AuthServiceTests.swift
func testSignInSuccess()
func testSignInFailure()
func testTokenRefresh()
func testLogout()
// StorageServiceTests.swift
func testSaveEntry()
func testFetchUnsynced()
func testMarkSynced()
func testDeleteOldData()
// APIClientTests.swift
func testAuthRequest()
func testScreenTimeUpload()
func testFetchCombinedData()
func testErrorHandling()
// SyncServiceTests.swift
func testBatchUpload()
func testRetryLogic()
func testOfflineQueue()
Cmd + U (or Product > Test)
git add .
git commit -m "Fix critical bugs"
DreamLauncherLite helps you track your screen time across all
your Apple devices in one place.
FEATURES:
• See your total screen time from iPhone, iPad, and Mac
• Weekly breakdown and trends
• Simple, privacy-focused design
• Automatic sync across devices
PRIVACY:
• Only collects total screen time duration
• No per-app tracking
• Data encrypted in transit
• You control your data
Product > Archive
This app requires Family Controls to access screen time data.
To test, please grant Family Controls permission when prompted.
The app syncs screen time to a backend server to enable
cross-platform tracking with our macOS app.
Demo account:
Email: demo@dreamlauncher.app
Password: [provide]
Wait for review (1-3 days)
Address feedback (if any)
Family Controls not authorizing:
Background sync not working:
API sync failing:
Data not appearing on macOS:
Developer:
Designer:
Product:
QA:
| Week | Focus | Deliverable |
|---|---|---|
| 1 | Core Foundation | Auth flow working |
| 2 | Screen Time | iOS data collection |
| 3 | API Sync | Data in backend |
| 4 | Cross-Platform | macOS data visible |
| 5 | Testing | Bug-free, polished |
| 6 | Submission | In App Review |
| 7+ | Iteration | Continuous improvement |
Total: 6-7 weeks from start to App Store
Let’s build this! 🚀