
PawScan
Pet Photo Journal · AI Notes
PawScan is a SwiftUI iOS photo-journal app for pet owners. Photos route through a self-hosted FastAPI backend proxy where OpenAI Vision (GPT-4o) drafts a warm, journal-style observation note and home-care tips, while the app tracks daily condition (appetite, water, activity, stool, mood), weight, and self-set vaccination and medication schedules in one place. It ships as a real product with SwiftData local storage, StoreKit 2 subscriptions, and 5-language localization, keeping the API key out of the app and centralizing prompt and model control on the server.
Day-to-day changes in a pet are hard to track when notes and photos are scattered, and writing up what you observed is tedious. PawScan gathers photos and daily logs into one journal and has AI draft the note for you, so owners can calmly review their pet's state before a vet visit. It is designed as an observation-logging tool, not a diagnostic one.
App preview
What it does
AI Photo Notes
Capture or pick a photo via PhotosUI; it is Base64-encoded and sent to the backend proxy (/api/v1/analyze). The server's OpenAI Vision (GPT-4o) returns a JSON observation-note draft across 8 categories (skin, eye, ear, oral, stool, vomit, behavior, other), a priority score, home-care tips, and a disclaimer. It is designed as a journaling note, not a medical diagnosis.
Daily Health Journal
Log appetite, water, activity, stool, and mood on a 1-5 scale each day, and review trends through a timeline and calendar. HealthLog entries persist in SwiftData, with a weekly health-score card. The free tier exposes only the last 7 days of history.
Vaccination & Medication Reminders
Self-set vaccination and medication schedules fire via UNCalendarNotificationTrigger. Daily/weekly/monthly recurring doses, multi-day early vaccination reminders, and a monthly free-analysis-reset reminder are all scheduled through UserNotifications.
Weight Tracker
Record WeightRecord entries and visualize trends with Swift Charts, with a mini-chart on the home screen summarizing recent movement; the free tier covers the last 30 days.
Food & Allergy Log
Track the current food brand (FoodRecord) and the pet's allergy tags. This context is included in the AI photo-note request body (active_food_brand, allergy_tags) and folded into the server-side prompt for richer notes.
Vet PDF Report
Render pet health records into a paginated PDF report with PDFKit's UIGraphicsPDFRenderer and share it with a vet via ShareSheet. A full JSON data export is also available for backup.
Home-Screen Widgets
Two WidgetKit widgets (small and medium) share data with the main app through an App Group (group.com.junsoft.PawScan), surfacing a daily summary such as today's condition and the next upcoming schedule.
Subscription & Premium Gating
StoreKit 2 offers monthly and yearly subscriptions and verifies entitlements via Transaction.currentEntitlements. The free tier is gated to 3 AI analyses per month, 1 pet, 7 days of health logs, and 30 days of weight records.
How it's built
iOS Core
Persistence
Apple Frameworks
Networking / AI
Backend
Localization
Tooling
A feature-organized SwiftUI MV(VM) architecture separating @Observable view models, a global AppState, a SwiftData persistence layer, actor-isolated network and AI layers, and a FastAPI backend proxy that wraps OpenAI Vision.
- 1
AI inference is not on-device; it routes through a self-hosted FastAPI backend proxy (pawscan-api) that calls OpenAI Vision (GPT-4o), keeping the API key out of the app and centralizing prompt, model, max_tokens, and temperature in server-side env vars.
- 2
The backend validates requests with FastAPI + Pydantic, calls OpenAI asynchronously via httpx with response_format=json_object for structured notes, applies per-IP rate limiting with slowapi (10/min free, 60/min premium), and deploys via Docker.
- 3
Network and AI services are isolated as actor singletons (APIClient, AIAnalysisService) and AppState and StoreService are @MainActor @Observable, aligning with the Swift 6 concurrency model for data-race safety; request and result types are Sendable.
- 4
Seven SwiftData @Model types (Pet, SymptomAnalysis, HealthLog, Vaccination, Medication, WeightRecord, FoodRecord) form deleteRule .cascade relationships rooted at Pet; enums (species, gender, category) are stored as raw strings and exposed via computed accessors, while compound values like allergy tags and possible causes are serialized.
- 5
An App Group (group.com.junsoft.PawScan) shares data between the main app and the WidgetKit extension, with WidgetDataProvider reading and writing summary data under the same identifier on both sides.
- 6
StoreKit 2 subscriptions gate premium: a Transaction.updates listener handles renewals, currentEntitlements verifies entitlements, and AppState counts monthly analyses to enforce the free limit (3/month).
- 7
Design tokens are centralized in PSColors, PSTypography, PSSpacing, and PSComponents to forbid hardcoded colors, fonts, and spacing, and the observation-note (not diagnosis) framing is kept consistent across both app and server copy.
84
Swift source files
7
SwiftData models
4
Main tabs
8
Note categories
2
Home widgets
5 (en, ko, ja, zh-Hans, es)
Localizations



