A beautiful iOS app for tracking meals, calories, and water intake with AI food recognition.
- Sign in with Apple - Secure authentication
- AI Food Recognition - Scan meals with your camera
- Real-time Sync - Data syncs across all your devices
- Nutrition Tracking - Calories, protein, carbs, and fat
- Water Intake - Track daily hydration
- Meal Photos - Visual food diary
- SwiftUI - Modern declarative UI
- Firebase - Backend services
- Authentication (Sign in with Apple)
- Firestore (Real-time database)
- Storage (Food photos)
- Analytics & Crashlytics
- MVVM Architecture - Clean separation of concerns
- Go to Firebase Console
- Click "Add project"
- Name it "Routine" (or your preferred name)
- Follow the setup wizard
- In Firebase Console, click "Add app" → iOS
- Enter bundle ID:
com.yourcompany.Routine(or your actual bundle ID) - Download
GoogleService-Info.plist - Add the file to your Xcode project (drag into Routine/ folder)
- Make sure "Copy items if needed" is checked
Note: GoogleService-Info.plist is gitignored for security. A template is available at GoogleService-Info.plist.template for reference.
- In Xcode: File → Add Package Dependencies
- Enter URL:
https://github.com/firebase/firebase-ios-sdk - Click "Add Package"
- Select these products:
- FirebaseAuth
- FirebaseFirestore
- FirebaseFirestoreSwift
- FirebaseStorage
- FirebaseAnalytics
- FirebaseCrashlytics
In Firebase Console:
- Go to Authentication → Sign-in method
- Enable "Apple" provider
- Add your Apple Developer Team ID
- Configure Service ID and Key (from Apple Developer portal)
In Xcode:
- Select project → Signing & Capabilities
- Click "+ Capability"
- Add "Sign in with Apple"
In Apple Developer Portal:
- Go to Certificates, Identifiers & Profiles
- Create a Service ID for Sign in with Apple
- Configure return URL:
https://routine-xxxxx.firebaseapp.com/__/auth/handler - Create and download private key
- In Firebase Console, go to Firestore Database
- Click "Create database"
- Start in Test mode (for development)
- Choose a location
Security Rules (for production):
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /foodEntries/{entryId} {
allow read, write: if request.auth != null &&
request.auth.uid == resource.data.userId;
allow create: if request.auth != null &&
request.auth.uid == request.resource.data.userId;
}
match /waterEntries/{entryId} {
allow read, write: if request.auth != null &&
request.auth.uid == resource.data.userId;
allow create: if request.auth != null &&
request.auth.uid == request.resource.data.userId;
}
}
}- In Firebase Console, go to Storage
- Click "Get started"
- Start in Test mode (for development)
Security Rules (for production):
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{userId}/food/{allPaths=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}Once Firebase SDK is added, uncomment the Firebase imports and code in:
Routine/RoutineApp.swift:
import FirebaseCore
// In init():
FirebaseApp.configure()GoogleService-Info.plistis gitignored and should never be committed to public repositories- This file contains your Firebase project configuration and API keys
- While the API key in this file is a public identifier (not a secret), it's best practice to keep it private
- Firebase security comes from Security Rules in Firestore and Storage, not from hiding this file
- For production apps, configure Security Rules to restrict access to authenticated users only (examples provided above)
Routine/Services/FirebaseManager.swift:
- Uncomment the Firebase implementation
- Remove the stub class
Routine/Services/AuthService.swift:
- Uncomment the Firebase Auth implementation
- Remove the stub class
Routine/Services/FirestoreService.swift:
- Replace stub methods with actual Firestore calls
Routine/Services/StorageService.swift:
- Replace stub methods with actual Storage calls
Routine/
├── RoutineApp.swift
├── ContentView.swift
├── Models/
│ ├── User.swift
│ ├── FoodEntry.swift
│ ├── WaterEntry.swift
│ └── DailySummary.swift
├── ViewModels/
│ ├── AuthViewModel.swift
│ ├── FoodLogViewModel.swift
│ └── WaterViewModel.swift
├── Views/
│ └── Auth/
│ └── LoginView.swift
├── Services/
│ ├── FirebaseManager.swift
│ ├── AuthService.swift
│ ├── FirestoreService.swift
│ ├── StorageService.swift
│ └── FoodRecognitionService.swift
└── GoogleService-Info.plist (you add this)
The app runs with mock data for UI development and testing.
- Complete all setup steps above
- Uncomment Firebase code
- Build and run on device or simulator
- Sign in with Apple (requires physical device for full test)
The app includes a mock AI food recognition service. For production, integrate one of:
- Firebase ML Kit - On-device image labeling
- Google Cloud Vision API - Via Firebase Functions
- Edamam Food Database - Nutrition data API
- Nutritionix API - Food database with NLP
- Clarifai - Food recognition API
- iOS 17.0+
- Xcode 15.0+
- Swift 5.9+
- Apple Developer Account (for Sign in with Apple)
MIT License - feel free to use this project as a starting point for your own apps.
For issues with:
- Firebase Setup: Check Firebase documentation
- Sign in with Apple: Verify Apple Developer configuration
- App Code: Open an issue on GitHub