A simplified Instagram-like feed for iOS demonstrating dynamic mixed media handling, optimized scrolling performance, and proper caching strategies.
| Requirement | Implementation |
|---|---|
| Scrollable feed with posts | ✅ List for efficient cell recycling |
| Single photo posts | ✅ SingleMediaView with natural aspect ratio |
| Single video posts | ✅ VideoPlayerView with auto-play support |
| Mixed photo + video posts | ✅ TabView carousel with PageTabViewStyle |
| Auto-play videos when visible | ✅ Visibility tracking via GeometryReader + PreferenceKey |
| Pause videos when scrolled out | ✅ Hysteresis-based visibility algorithm in FeedViewModel |
| Caching mechanisms | ✅ ImageCacheActor and VideoCacheActor using Swift actors |
| External data source | ✅ Mock data from picsum.photos, pravatar.cc, and Google sample videos |
- iOS: SwiftUI
- Architecture: MVVM (Model-View-ViewModel)
- Concurrency: Swift Concurrency (
async/await,actor) - Video Playback: AVFoundation / AVKit
┌─────────────────────────────────────────────────────────────┐
│ InstaFeedApp │
│ (DependencyContainer) │
└─────────────────────────────────────────────────────────────┘
│
@Environment(\.dependencies)
│
┌─────────────────────────────────────────────────────────────┐
│ FeedView │
│ + FeedViewModel │
│ (visibility tracking, scroll logic) │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────┐
│ PostView │
│ + PostViewModel │
│ (PostHeaderView, PostMediaContentView, │
│ PostActionsView, PostCaptionView) │
└─────────────────────────────────────────────────────────────┘
│
┌──────────────────┴──────────────────┐
│ │
┌─────────────────────┐ ┌─────────────────────┐
│ CachedAsyncImage │ │ VideoPlayerView │
│ + ImageLoaderService│ │ + VideoPlayerVM │
└─────────────────────┘ └─────────────────────┘
│ │
┌─────────────────────┐ ┌─────────────────────┐
│ ImageCacheActor │ │ VideoCacheActor │
│ (thread-safe) │ │ (thread-safe) │
└─────────────────────┘ └─────────────────────┘
- Uses
Listfor efficient memory management through cell recycling - Handles hundreds of posts without memory bloat
- Single Image: Displays with natural aspect ratio
- Single Video: Auto-plays with natural aspect ratio
- Carousel:
TabViewwith page indicator for multiple items
- Tracks visibility using
GeometryReaderandPreferenceKey - Hysteresis algorithm: Videos keep playing until < 30% visible, new videos start at > 50% visible
- Prevents flickering during slow scrolling
| Cache | Type | Purpose |
|---|---|---|
ImageCacheActor |
actor |
Thread-safe in-memory image cache with LRU eviction |
VideoCacheActor |
actor |
Thread-safe AVAsset cache to avoid reloading metadata |
VideoPlayerCacheActor |
actor |
Reuses AVPlayer instances per URL |
- No singletons — all services created in
DependencyContainer - Injected via
@Environment(\.dependencies)
- Open
InstaFeed.xcodeprojin Xcode - Select the
InstaFeedscheme - Choose a simulator or device
- Press
Cmd + Rto build and run
Note: Internet connection required for loading mock media from external URLs.
The app uses external services for mock data:
- Images: picsum.photos (Lorem Picsum)
- Avatars: pravatar.cc (Random avatars)
- Videos: Google sample videos (Big Buck Bunny, Elephants Dream)
- Disk caching for offline support
- Pull-to-refresh
- Infinite scroll / pagination
- Like/comment interactions
- Local video/image assets as alternative data source