Skip to content

Repository files navigation

ParentHelper

A local-first iOS assistant for a parent who does not read English and is not comfortable navigating a phone. Everything is translated to Simplified Chinese and read aloud. Personal data is processed on-device — no third-party cloud AI.

Built from ParentHelper/Parent helper.md. This README covers setup; the code is heavily commented inline.

What this app is intended to do

ParentHelper is a native SwiftUI iPhone app that acts as a personal, easy-to-use assistant for a parent who does not read English and cannot navigate a phone independently. It exists to let that person handle everyday digital chores — reading email and understanding a government or account website — without needing to read English or hunt through unfamiliar screens.

Core promises

  • Everything in Simplified Chinese, read aloud. Every screen, summary, and action is translated to Chinese and spoken via text-to-speech. Nothing requires reading English.
  • Privacy-first, on-device AI. Personal data (emails, bills, account info) is never sent to a third-party cloud AI. All AI reasoning (summarize, classify, pick next step) runs on-device via Apple's Foundation Models; translation runs on-device via Apple's Translation framework. The AI backend is swappable and defaults to fully on-device.
  • Task-based, not open-ended. The home screen is a grid of large icon tiles, each a scripted "flow" with fixed steps. The AI only fills variable parts (translation, summarization, next-step / on-screen-action selection) — it never improvises whole flows or generates things like CSS selectors.
  • Accessible by design. Big icon-based buttons, minimal text, oversized components, spoken guidance — no reliance on reading or precise navigation.

Scope guardrails

  • Reliability, privacy, and simplicity are prioritized over feature breadth.
  • Email uses the Gmail API inside our own native mail screen (not an embedded Gmail WebView), with bounded 30-day + incremental historyId sync — never a full mailbox re-pull.
  • Website help is a guided in-app browser over a small set of known sites with hand-authored action taxonomies + selectors, not a general-purpose agent.

User Experience / Use Cases

What are the key scenarios you want to nail? (rank by importance)

  1. Scenario: User want to go read their email, and understand it.
    • Trigger (what makes them open the app): to go through email
    • What they should see / hear: list of their email: opened/unopened, past 30 days
    • What "success" looks like: user opens an email, and the user can choose to summarize or click on the screen to box or select which part they want to translate, the app also explain what this is about in short sentences. The app reads them in mandarine.
  2. Scenario: The email shows a bill, the user want to understand it, but it requires user to go into company website
    • Trigger: user click on the link provided in the email
    • What they should see / hear: if they press on the summarize button, they should hear the app summarizing what this is about, and tells them that there is a link. If they click on the link they see the website. then the app also has the 2 buttons for either select parts or summarize whole thing, and read them actional actions.
    • Success: The user sucessfully sees the bill
  3. Scenario: Similar to scenario 2, but for paying bills.
    • Trigger:
    • What they should see / hear:
    • Success:

Non-goals — what this app should deliberately NOT do

  • Replying to / composing messages. The app is read-and-understand only; it does not send email or compose replies on the user's behalf.

What works today

  • Foundation layer (build order §1): TranslationService (Apple Translation framework, on-device) and SpeechService (AVSpeechSynthesizer, zh-CN) as standalone pieces.
  • "Read New Emails" end-to-end (build order §2): Gmail OAuth → bounded 30-day sync + incremental historyId sync → on-device summarization in Chinese (Foundation Models) → read aloud.
  • "Reply to a Message": compose in Chinese → translate to English → send via Gmail API.

Scaffolded (extend these — build order §3–5)

  • "Understand a Website" guided browser: WKWebView + injected snapshot / highlight user scripts, on-device action classification against an authored taxonomy, icon action buttons. The mechanism is complete; the site data in Features/Browser/ActionTaxonomy.swift is placeholder — fill in real hosts + hand-verified CSS selectors.
  • Swappable AI backend (§5): RemoteAIAssistant stub conforms to the same AIAssistant protocol as the on-device backend; swap in AIAssistantProvider.

Project structure

ParentHelper/
  App/            AppServices (DI), AppTheme, Strings
  Models/         EmailMessage, HelperTask
  Services/
    Speech/       SpeechService            (§1)
    Translation/  TranslationService       (§1)
    AI/           AIAssistant protocol, FoundationModelsAssistant (default,
                  on-device), RemoteAIAssistant (stub), AIAssistantProvider
    Gmail/        Auth (OAuth+PKCE), API, SyncEngine (30-day + historyId),
                  MessageParser, TokenStore (Keychain), models
  Features/
    Home/         HomeView (task tiles)
    Email/        List/Detail/Reply views + view models (MVVM, @Observable)
    Browser/      Guided browser (scaffold)
    Settings/     Account + AI status
  Config/         Secrets.swift  ← fill this in
  Support/        Reusable oversized components

Architecture: MVVM with @Observable (Observation, iOS 17+). Views are thin; all state lives in @Observable view models constructed with injected services.

Requirements

  • Xcode 26+, deployment target iOS 26.0 (already set).
  • Apple Intelligence-capable device for on-device AI: iPhone 15 Pro / Pro Max or newer (A17 Pro+). The Foundation Models summarizer reports "unavailable" on other devices and the app falls back to translating the email snippet.
  • The Simulator can run the UI; Foundation Models availability depends on the Mac/Simulator supporting Apple Intelligence. Translation + speech work broadly.

Setup

1. Signing

The project already has a bundle id com.ParentHelper and a development team. Adjust PRODUCT_BUNDLE_IDENTIFIER / DEVELOPMENT_TEAM in project settings for your own Apple Developer account.

2. Gmail API OAuth credentials

No credentials are bundled. To enable email:

  1. Google Cloud Console → create a project.

  2. Enable the Gmail API (APIs & Services → Library → Gmail API).

  3. OAuth consent screen: User type External. While unverified, add the parent's Gmail address under Test users. Scopes used: gmail.readonly, gmail.send, userinfo.email.

  4. Credentials → Create OAuth client ID → Application type: iOS. Use bundle id com.ParentHelper. Google gives you:

    • a client id like 1234-abcd.apps.googleusercontent.com
    • a reversed client id like com.googleusercontent.apps.1234-abcd
  5. Paste both into ParentHelper/Config/Secrets.swift (googleClientID, googleRedirectScheme = the reversed client id).

  6. Register the redirect URL scheme so ASWebAuthenticationSession can return: Target → Info → URL Types → add a URL Type whose URL Schemes is the reversed client id (e.g. com.googleusercontent.apps.1234-abcd).

    Because this target uses GENERATE_INFOPLIST_FILE = YES, add the URL Type via the target's Info tab in Xcode (it writes to the generated Info.plist), or add a custom Info.plist with a CFBundleURLTypes array and point INFOPLIST_FILE at it.

Until real values are in Secrets.swift, the email screen shows a friendly "setup needed" state instead of attempting OAuth.

3. Run

Build & run on an Apple-Intelligence device (or Simulator for UI). Tap 读新邮件 ("Read new emails") → 登录邮箱 to start the Gmail OAuth flow.

Privacy notes

  • Email/website content is summarized/classified on-device via Foundation Models. Translation is on-device via Apple's Translation framework.
  • OAuth tokens are stored in the Keychain (TokenStore).
  • The only network calls are directly to Google's Gmail API (the user's own mailbox). No third-party AI service is contacted.
  • RemoteAIAssistant is disabled by default; if ever enabled it must point only at a family-controlled machine on a private VPN (e.g. Tailscale), never a public cloud AI API.

Key design decisions

  • Task-based home, not open-ended. Each tile is an authored flow; the AI only fills variable parts (summarize / classify / pick next known step).
  • No selectors from the model. The guided browser keeps a hardcoded (site, action) → selector map; the model only classifies which authored actions are on screen (avoids hallucinated selectors).
  • No embedded Gmail WebView. Google blocks OAuth in embedded browsers, so we use the Gmail API inside our own SwiftUI mail screen with ASWebAuthenticationSession for login.
  • Bounded sync. Initial pull is last 30 days only; thereafter incremental via historyId. On an expired cursor (404) we re-run the 30-day sync — never a full mailbox re-pull.
  • Swappable AI. The UI depends only on the AIAssistant protocol.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages