A modern iOS recipe discovery app built with SwiftUI, featuring real-time data from TheMealDB API, persistent favorites, and a beautiful shimmer loading system.
- Top Dishes - Curated meals from popular categories
- Chef's Picks - 10 unique random meal recommendations (deduplicated from 15 concurrent API calls)
- Categories - Browse all meal categories with beautiful image cards
- Ingredient Spotlight - Discover meals by popular ingredients
- ❤️ Tap to favorite any meal from anywhere in the app
- 📌 Persistent storage across app launches
- 🔄 Real-time synchronization across all tabs
- 📊 Dedicated favorites screen with empty state
- 🗑️ Context menu for quick removal
- ✨ Shimmer loading states for all sections
- 🎯 Independent section loading (no blocking)
- 🔄 Pull-to-refresh on all screens
- 📱 Smooth 60fps scrolling
- 🎨 Light and dark mode support
- ♿ Full accessibility (VoiceOver, Reduce Motion, Dynamic Type)
- 📳 Haptic feedback on interactions
Built with Clean Architecture principles and MVVM pattern:
┌─────────────────────────────────────────────────┐
│ Views (SwiftUI) │
│ HomeScreen, CategoriesScreen, etc. │
└────────────────────┬────────────────────────────┘
│
┌────────────────────▼────────────────────────────┐
│ ViewModels (@MainActor) │
│ HomeViewModel, FavoritesStore, etc. │
└────────────────────┬────────────────────────────┘
│
┌────────────────────▼────────────────────────────┐
│ Repository (Protocol) │
│ RecipeRepository - Data Abstraction │
└────────────────────┬────────────────────────────┘
│
┌────────────────────▼────────────────────────────┐
│ API Client (Protocol) │
│ Domain-specific API methods │
└────────────────────┬────────────────────────────┘
│
┌────────────────────▼────────────────────────────┐
│ Network Service │
│ Swift Concurrency (async/await) │
└─────────────────────────────────────────────────┘
- Dependency Injection - DIContainer manages all dependencies
- Protocol-Oriented - Every layer uses protocols for testability
- Single Source of Truth - FavoritesStore for cross-tab state
- Repository Pattern - Abstracts data source from business logic
- MVVM - Clear separation between Views and ViewModels
// Parallel API calls for optimal performance
async let categories = loadCategories()
async let chefsPicks = loadChefsPicks()
async let ingredients = loadIngredients()
await categories
await loadTopDishes() // Depends on categories
await chefsPicks
await ingredients// Reusable shimmer effect
view.shimmer()
// Pre-built skeleton components
SkeletonMealCard()
SkeletonCategoryCard()
SkeletonIngredientCard()// FavoritesStore - Single source of truth
@EnvironmentObject var favoritesStore: FavoritesStore
// Instant updates across all tabs
favoritesStore.toggleFavorite(mealId)RecipeApp/
├── App/
│ └── RecipeApp.swift # App entry point
├── DI/
│ └── DIContainer.swift # Dependency injection
├── Services/
│ └── FavoritesStore.swift # Favorites management
├── Networking/
│ ├── NetworkModels.swift # API endpoints & config
│ ├── NetworkService.swift # HTTP layer
│ └── APIClient.swift # Domain-specific methods
├── Repositories/
│ └── RecipeRepository.swift # Data abstraction layer
├── Models/
│ └── RecipeModels.swift # Domain models (DTOs)
├── ViewModels/
│ ├── HomeViewModel.swift # Home screen logic
│ ├── MealsListViewModel.swift # Meals list logic
│ └── MealDetailViewModel.swift # Detail screen logic
├── Views/
│ ├── Screens/
│ │ ├── HomeScreen.swift # Tab #1 - Home
│ │ ├── CategoriesScreen.swift # Tab #2 - Categories
│ │ ├── FavoritesScreen.swift # Tab #3 - Favorites
│ │ ├── MealsListView.swift # Meals grid
│ │ └── MealDetailView.swift # Recipe details
│ └── Components/
│ ├── ShimmerView.swift # Loading skeletons
│ ├── CategoryCardView.swift # Category cards
│ ├── MealCardView.swift # Meal cards
│ ├── IngredientCardView.swift # Ingredient cards
│ └── TabBar.swift # Custom tab bar
└── Resources/
└── Colors/
└── ColorManager.swift # Theme colors
- Home - Discovery hub with curated sections
- Categories - Full grid of all meal categories
- Favorites - Saved recipes with persistent storage
- Profile - User settings (placeholder)
- Colors: Semantic color system via ColorManager
- Typography: Dynamic Type with custom Poppins font
- Spacing: Consistent 8pt grid system
- Cards: Rounded corners, subtle shadows, hover states
- Animations: Smooth 0.3s transitions with easing
- ✅ VoiceOver labels for all interactive elements
- ✅ Reduce Motion support (disables shimmer animation)
- ✅ Dynamic Type scaling
- ✅ High contrast support
- ✅ Semantic color names
- ✅ Minimum touch target sizes (44x44pt)
Base URL: https://www.themealdb.com/api/json/v1/1/
Endpoints Used:
GET /categories.php- All categoriesGET /filter.php?c={category}- Meals by categoryGET /filter.php?i={ingredient}- Meals by ingredientGET /lookup.php?i={id}- Meal detailsGET /random.php- Random mealGET /list.php?i=list- All ingredients
Performance:
- Parallel concurrent requests
- In-memory caching for favorites
- Deduplication of random meals
- System URLCache for images
- Technology: UserDefaults (JSON encoding)
- Key:
com.recipeapp.favorites - Format: Array of meal IDs
- Cache: In-memory meal details cache
- Sync: Instant cross-tab updates via ObservableObject
- iOS: 15.0+
- Xcode: 15.0+
- Swift: 5.9+
- Devices: iPhone (all sizes), iPad (compatible)
- Clone the repository
git clone https://github.com/yourusername/RecipeApp.git
cd RecipeApp- Open in Xcode
open RecipeApp.xcodeproj- Build and Run
- Select your target device/simulator
- Press
⌘Ror click the Run button - No additional configuration needed!
- Home loads with shimmer then content
- Categories tab shows full grid
- Favorites persist across app kills
- Heart buttons update instantly everywhere
- Pull-to-refresh works on all screens
- Navigation flows work correctly
- Works in light and dark mode
- VoiceOver reads all content
- Reduce Motion disables animations
- Skeletons appear: < 150ms
- Categories complete: ~500ms
- Top Dishes complete: ~800ms
- Chef's Picks complete: ~1500ms (15 parallel calls)
- Ingredients complete: ~600ms
- Idle: ~30MB
- Loading: ~50MB
- Peak: ~80MB (with images)
- 18 concurrent calls on Home load
- Deduplication prevents duplicate meals
- Caching reduces redundant requests
- Search functionality
- Recipe ratings and reviews
- Meal planning and scheduling
- Shopping list generation
- Cooking timer and step-by-step mode
- Share recipes via social media
- Offline mode for favorites
- Core Data migration for advanced persistence
- CloudKit sync across devices
- Widget support
- Background refresh
- Unit and UI tests
- Analytics integration
This project is licensed under the MIT License - see the LICENSE file for details.
Ahmed El-Elaimy
- GitHub: @ahmedel-elaimy
- LinkedIn: Ahmed El-Elaimy
- TheMealDB - Free meal database API
- Design Inspiration - Modern iOS app design patterns
- Community - SwiftUI and iOS development community
This is a portfolio project showcasing:
- ✅ Modern Swift & SwiftUI development
- ✅ Clean Architecture principles
- ✅ MVVM pattern implementation
- ✅ Swift Concurrency (async/await)
- ✅ Protocol-Oriented Programming
- ✅ Dependency Injection
- ✅ State management
- ✅ Networking & API integration
- ✅ Data persistence
- ✅ UI/UX best practices
- ✅ Accessibility support
Zero External Dependencies - Pure Swift with no CocoaPods or SPM packages required.
⭐ If you found this project helpful, please consider giving it a star!