ExpenseTracker is a privacy-first iOS app that reads transaction emails from Gmail, extracts card spends, and shows them in a clean on-device dashboard.
The app is designed around a simple idea: your data should stay on your phone. Gmail access is read-only, processing happens locally, and the app does not send your financial data to the author or any backend.
- Signs in with Google using Gmail read-only access
- Reads transaction emails directly on the device
- Extracts useful transaction details from supported bank email formats
- Stores parsed transactions locally on the device
- Shows dashboards, recent transactions, spending by category, and card summaries
- Lets you manage cards, sender rules, and sync state from inside the app
- Gmail permission requested by the app is read-only:
https://www.googleapis.com/auth/gmail.readonly - Tokens are stored in the iOS Keychain on the device
- Parsed transaction data is stored locally on the device
- No analytics, no cloud sync, and no server-side storage are used by this project
- Raw email content is processed in memory and is not intended to be uploaded anywhere
If you trust the author and prefer not to build the project yourself, you can install the app from the iOS App Store when it is available there and grant Gmail read access during sign-in. Even then, the app is built so that your Gmail data and parsed transaction data remain on your device, and the author does not have a built-in way to view or use that personal data.
- The app signs in with Google OAuth using a client you configure for iOS.
- It requests read-only access to Gmail.
- Matching transaction emails are fetched from Gmail.
- Transaction details are parsed locally.
- Results are stored in local app storage and displayed in the dashboard.
- A Mac with Xcode installed
- An Apple ID for signing to your personal device
- An iPhone or iPad if you want to test on real hardware
- A Google Cloud project with an iOS OAuth client
git clone <your-repo-url>
cd ExpenseTrackerCopy the example file:
cp ExpenseTracker/Config/Secrets.swift.example ExpenseTracker/Config/Secrets.swiftThen update ExpenseTracker/Config/Secrets.swift with:
- Your Google iOS OAuth client ID
- Your Google redirect URI
This file is gitignored and should never be committed.
In Google Cloud Console:
- Open
APIs & Services - Go to
Credentials - Create an
OAuth 2.0 Client ID - Choose application type
iOS - Use your iOS bundle identifier
You will get a client ID that looks like:
YOUR_CLIENT_ID.apps.googleusercontent.com
Your redirect URI should look like:
com.googleusercontent.apps.YOUR_CLIENT_ID_PREFIX:/oauth2redirect
The callback URL scheme in ExpenseTracker/Info.plist must match the reversed client ID for your Google OAuth app.
If you use your own Google credentials, replace the existing scheme with your own reversed client ID.
Open:
Then in Xcode:
- Select the
ExpenseTrackertarget - Set your Team under
Signing & Capabilities - Confirm the bundle identifier matches your setup
- Choose your iPhone or iPad as the run destination
Press Run in Xcode. On first launch:
- Sign in with Google
- Grant Gmail read-only access
- Add or review supported sender addresses if needed
- Trigger sync and review transactions on the dashboard
- This app is intended to be privacy-first and local-first
- Gmail access is only used to read transaction emails needed for parsing
- The author does not operate a backend for storing your mailbox or transactions
- Your trust decision should still be your own, and you should review the code or build it yourself if you want maximum assurance
The repository is set up so local secrets and local Xcode user data should not be committed. In particular:
ExpenseTracker/Config/Secrets.swiftshould stay localxcuserdatashould stay out of git- Generated build output and local databases should stay out of git
This is an app-directory project intended for local development in Xcode. If you plan to share it publicly, review:
- OAuth app configuration
- Supported sender rules and parser coverage
- App Store privacy disclosures
- Wording in the sign-in and privacy experience