Skip to content
All case studies

Mobile · iOS · SwiftUI

Leopard iOS App

Leopard is the app I open every morning, built natively in SwiftUI for iOS 15 so it runs on an iPhone 7. It turns a 12-week study plan into local notifications with a focus timer and progress tracking, reads a daily news and football briefing prepared by a server job, carries a native private chat, and doubles as a console for everything I run: Vercel deployments, GitHub, Supabase, Resend, uptime, Search Console, and the content of this website.

Role
Designer & iOS developer
Client
Own product
Timeline
Jun 2026 – present
Year
2026
Leopard iOS App — A personal SwiftUI app for study, focus, news, chat, and running my sites

Native SwiftUI for iOS 15, with no third-party packages

Hand-written Supabase Realtime client for the private chat

Edits this portfolio: gallery, projects, and certifications

Overview

I wanted one place on my phone for what I actually do each day: work through a study plan, protect focus time, catch up on the news, keep a private conversation going, and watch over the sites and services I run. Leopard started as a study-reminder app and grew into that place, built for the phone I carry, an iPhone 7 on iOS 15.

What I built

A SwiftUI app with five tabs (Today, Schedule, Tracker, Briefing, and Chat) and a Console. Study state lives on the device and reminders are scheduled locally, so the core of the app works with no server and no signal. The briefing is written once a day by a cron job on this site and stored in Supabase; the app reads it with the public key and keeps a copy for offline mornings.

The chat began as a web view of the site's messenger, but loading the Next.js bundle on an iPhone 7 took seconds on every cold start. I rewrote it natively, including a small Supabase Realtime client with no dependencies, and kept the web layer only for WebRTC calls. The Console talks to each service with tokens from the Keychain, while anything that needs a server secret, like Search Console data or editing this site, goes through dedicated routes on iamleopard.com.

Built for older hardware

iOS 15 lacks several newer SwiftUI APIs, so the app carries small shims instead of raising its minimum version. The focus timer stores when it ends rather than ticking a counter, so it stays right after the app is suspended or killed. XCUITest flows drive Today, Schedule, Tracker, and the chat end to end on the simulator and capture screenshots for visual review.

Key features

Today screen with the current study block, a 25, 50 or 90-minute focus timer that survives the app being killed, a morning check-in streak, and personal tasks

A 12-week plan delivered as local notifications, refilling iOS's 64-notification window every time the app opens

Schedule and Tracker: week-by-week blocks to tick off, progress by subject, streaks, and a 7-day focus chart

Daily briefing of news stories with short summaries plus football standings and fixtures, cached for offline reading

Native private chat on a Supabase Realtime (Phoenix v2) client written over URLSessionWebSocketTask, with presence and cached photos

Console for Vercel deployments, GitHub, Supabase projects, Resend email, uptime checks, Search Console, and a Kanban board

Content admin for iamleopard.com: photos upload straight to Supabase Storage and the site regenerates on the next visit

Service tokens live only in the iOS Keychain; anything that needs a server secret goes through narrow bearer-token routes

Built with

SwiftSwiftUIUserNotificationsURLSession WebSocketsKeychainXCTestSupabaseNext.js API routes

Have a project like this?

I take products from first sketch to shipped, design, build, and the AI in between. Tell me what you’re working on.

More work