MealsApp — iOS Learning Project (Modular VIPER + Multi-Architecture Exploration)
Aplikasi iOS native untuk browsing dan mencari resep makanan — project learning yang mengeksplorasi berbagai arsitektur iOS (VIPER modular, SPM), reactive programming paradigm (Callback, Combine, RXSwift), dependency injection, dan local database. Dilengkapi dokumentasi arsitektur lengkap berupa flowchart.
- Role
- iOS Developer
- Ownership
- Solo builder: arsitektur VIPER, modularisasi SPM, migrasi networking, reactive programming (Callback/Combine/RXSwift), DI (SwiftInject), RealmSwift.
- Company
- Personal Project
- Client
- Self-learning — portfolio project untuk menunjukkan kemampuan iOS development dan arsitektur
- Team
- Solo
- Period
- 2025
- Focus
- iOS, iOS Developer, Swift, Mobile Developer
Overview
MealsApp adalah aplikasi iOS native untuk browsing kategori makanan, melihat daftar resep per kategori, mencari resep, melihat detail resep, dan menyimpan resep favorit ke local database. Aplikasi ini mengonsumsi TheMealDB API sebagai sumber data.
Project ini adalah learning project yang dirancang khusus untuk mengeksplorasi dan mendokumentasikan berbagai pendekatan arsitektur iOS secara sistematis. Setiap branch di repository mewakili tahap evolusi arsitektur yang berbeda — dari monolitik berbasis callback hingga modular VIPER dengan Swift Package Manager.
Yang membedakan project ini dari tutorial biasa adalah dokumentasi arsitekturnya yang lengkap: setiap layer, flow, dan object relationship didokumentasikan dalam bentuk flowchart di README, menjadikannya referensi visual yang bisa dipelajari kembali.
Tech & Libraries
Teknologi dan library yang dipakai atau disentuh di project ini:
Problem
Sebagai seorang iOS developer yang ingin meningkatkan kemampuan arsitektur, saya menghadapi beberapa tantangan:
- Bagaimana cara mendokumentasikan arsitektur iOS secara visual dan sistematis agar bisa dipelajari kembali dan dipresentasikan ke recruiter?
- Bagaimana transisi dari arsitektur monolitik (semua kode di satu target) ke arsitektur modular dengan Swift Package Manager?
- Bagaimana perbandingan implementasi reactive programming menggunakan Callback tradisional vs Apple Combine framework vs RXSwift?
- Bagaimana cara mengimplementasikan dependency injection secara terstruktur dengan SwiftInject?
- Bagaimana mengintegrasikan local database (RealmSwift) untuk fitur favorites tanpa mengubah arsitektur yang sudah ada?
Project ini sengaja dibuat sebagai learning sandbox untuk menjawab pertanyaan-pertanyaan tersebut dengan pendekatan hands-on dan terdokumentasi.
My Role & Ownership
Solo builder: arsitektur VIPER, modularisasi SPM, migrasi networking, reactive programming (Callback/Combine/RXSwift), DI (SwiftInject), RealmSwift.
Technical Approach
Technical Approach:
MealsApp dibangun dengan arsitektur VIPER (View, Interactor, Presenter, Entity, Router) yang dimodularisasi menggunakan Swift Package Manager. Setiap fitur (Home, Category, Meal, Favorite, Search, About) dipisahkan menjadi package SPM independen yang bisa dikembangkan dan di-test secara terpisah.
Stack utama yang digunakan: - SwiftUI untuk UI layer dengan pendekatan programmatic - VIPER pattern untuk separation of concerns yang ketat - URLSession / Alamofire untuk networking layer (ada branch yang mengeksplorasi migrasi dari URLSession ke Alamofire) - TheMealDB API sebagai data source publik - RealmSwift untuk local database penyimpanan favorites - SwiftInject untuk dependency injection - Combine / RXSwift untuk reactive programming (ada branch yang mengeksplorasi migrasi dari Callback ke Combine dan dari Callback ke RXSwift)
Flow implementasi:
- View mengirim event ke Presenter
- Presenter memanggil Interactor untuk business logic
- Interactor menggunakan Repository untuk mengambil data dari remote API atau local database
- Repository mengembalikan data melalui completion handler atau reactive stream
- Presenter memformat data dan mengirimkan ViewState ke View
- Router menangani navigasi antar module
Setiap layer memiliki protocol abstraction yang jelas, memungkinkan swapping implementasi (misalnya URLSession ke Alamofire, Callback ke Combine) tanpa mengubah layer di atasnya.
Architecture Notes
Struktur sistem terdiri dari beberapa layer dengan dependency direction yang ketat:
- SharedInfra — package infrastruktur dasar: APICall protocol, network configuration, base classes untuk repository. Semua package lain depend ke sini.
- Core — package inti: Entity definitions, protocol repository, dan use case interfaces.
- Common — package utilitas bersama: extensions, helper functions, constants.
- Feature packages (Category, Meals, Home, MealView, FavoriteView, SearchView, AboutMe) — masing-masing berisi implementasi VIPER lengkap: View, Interactor, Presenter, Entity, Router, dan Repository implementation.
Data flow: - Remote: TheMealDB API → Repository (URLSession/Alamofire) → Interactor → Presenter → View - Local: RealmSwift → LocalDataSource → Repository → Interactor → Presenter → View - Favorites: View → Presenter → Interactor → Repository → LocalDataSource (RealmSwift)
State management: - Callback-based: completion handler pattern dengan Result type - Combine-based: PassthroughSubject dan CurrentValueSubject untuk reactive stream - RXSwift-based: Observable dan BehaviorRelay untuk reactive stream
Dependency injection menggunakan SwiftInject (Swinject-based) yang di-register di AppDelegate/SceneDelegate, memungkinkan mocking untuk testing.
Trade-offs
Keputusan arsitektur kunci:
- VIPER vs MVVM — VIPER dipilih karena memberikan separation of concerns yang paling ketat dengan 5 layer terpisah. Konsekuensinya: lebih banyak boilerplate code dibanding MVVM, tapi setiap layer memiliki tanggung jawab yang jelas dan mudah di-test secara independen.
- Modular SPM vs Monolitik — Modularisasi dengan SPM memungkinkan pengembangan dan testing fitur secara independen, serta reuse package ke project lain. Konsekuensinya: kompleksitas dependency graph meningkat, dan perubahan di SharedInfra/Core memerlukan version bump di semua package yang depend.
- URLSession vs Alamofire — URLSession digunakan di branch utama karena zero dependency dan cukup untuk kebutuhan REST API sederhana. Branch change-urlsession-alamofire mengeksplorasi Alamofire untuk request chaining yang lebih ekspresif. Trade-off: Alamofire menambah dependency size tapi memberikan syntax yang lebih clean untuk request/response handling.
- Callback vs Combine vs RXSwift — Tiga branch berbeda mengeksplorasi ketiga paradigm ini. Callback: simplest, zero dependency, tapi callback hell untuk nested requests. Combine: native Apple, declarative, iOS 13+ only. RXSwift: mature ecosystem, lebih banyak operator, tapi third-party dependency. Keputusan: branch utama menggunakan Callback untuk kompatibilitas maksimal, dengan branch eksplorasi untuk Combine dan RXSwift.
- RealmSwift vs CoreData — RealmSwift dipilih karena API yang lebih straightforward dan performa yang baik untuk use case sederhana (favorites). CoreData lebih native tapi memerlukan lebih banyak boilerplate untuk setup yang setara.
Implementation Highlights
- Arsitektur VIPER modular dengan 7+ SPM package independen yang bisa di-test secara terpisah
- Dokumentasi arsitektur visual lengkap: flowchart untuk setiap layer, flow, dan object relationship di README
- Multi-branch architecture exploration: 10+ branch dengan pendekatan arsitektur berbeda (Callback, Combine, RXSwift, Alamofire, VIPER, SwiftInject)
- Migrasi dari monolitik ke modular architecture tanpa mengubah fungsionalitas aplikasi
- Implementasi 3 paradigm reactive programming dalam branch terpisah untuk perbandingan langsung
- Dependency injection terstruktur dengan SwiftInject untuk testability
- Integrasi local database (RealmSwift) untuk fitur favorites dengan abstraction layer
- CI/CD pipeline dengan CodeMagic untuk build automation
- Figma board untuk perencanaan arsitektur visual sebelum implementasi
Results
- Project learning yang mendemonstrasikan penguasaan arsitektur iOS modern: dari monolitik ke modular VIPER dengan SPM, migrasi networking (URLSession → Alamofire), reactive programming (Callback → Combine → RXSwift), dependency injection (SwiftInject), dan local database (RealmSwift). Dilengkapi dokumentasi arsitektur visual berupa flowchart untuk setiap layer.
- Learning project yang berhasil mendokumentasikan perbandingan 3 paradigm reactive programming (Callback, Combine, RXSwift) dalam branch terpisah
- Berhasil memigrasi arsitektur dari monolitik ke modular VIPER dengan 7+ SPM package tanpa regresi fungsionalitas
- Dokumentasi arsitektur visual berupa 10+ flowchart yang mencakup setiap layer, flow data, dan object relationship
- Repository dengan 10+ branch yang masing-masing mewakili eksplorasi arsitektur berbeda — bisa dijadikan referensi belajar bagi iOS developer lain
- Certificate of Completion dari kursus iOS VIPER Architecture sebagai bukti pembelajaran terstruktur
- 10+ branch arsitektur berbeda dalam satu repository
- 7+ SPM package modular
- 10+ flowchart dokumentasi arsitektur
- 3 paradigm reactive programming dieksplorasi (Callback, Combine, RXSwift)
- Migrasi dari CocoaPods ke SPM (zero pod dependency di branch utama)
- Certificate of Completion: iOS VIPER Architecture