██████╗ ██╗████████╗ ███████╗ ██████╗ ██╗ ██╗ ██████╗ ██╗ ██╗
██╔════╝ ██║╚══██╔══╝ ██╔════╝██╔═══██╗██║ ██║ ██╔═══██╗██║ ██║
██║ ███╗██║ ██║ █████╗ ██║ ██║██║ ██║ ██║ ██║██║ █╗ ██║
██║ ██║██║ ██║ ██╔══╝ ██║ ██║██║ ██║ ██║ ██║██║███╗██║
╚██████╔╝██║ ██║ ██║ ╚██████╔╝███████╗ ███████╗╚██████╔╝╚███╔███╔╝
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝
Browse GitHub profiles. Discover followers. Save your favourites.
Git Follow is an iOS application that lets you explore the GitHub social graph — search any GitHub username, browse their followers, dive into profiles, and save your favourite users for quick access later. Built with a focus on clean architecture, real-world iOS engineering practices, and a fully programmatic UI (zero storyboards).
| Feature | Description |
|---|---|
| 🔍 User Search | Search any GitHub username instantly via the public GitHub REST API |
| 👥 Followers List | Paginated list of all followers for any given user |
| 👤 User Detail | Rich profile view with avatar, bio, repos, following & followers count |
| 🌐 Profile WebView | Open the full GitHub profile in-app via a native WKWebView |
| ⭐ Favourites | Save users to a persistent favourites list backed by UserDefaults |
| 📦 Caching | Avatar images cached in memory with NSCache to reduce network calls |
| 📄 Pagination | Infinite scroll — followers load in batches as you scroll |
This project was built to demonstrate real-world iOS development patterns, not just feature delivery.
┌─────────────────────────────────────────────────────┐
│ Engineering Focus │
├──────────────────────┬──────────────────────────────-┤
│ 🌐 Networking │ URLSession + async/await │
│ 📄 Pagination │ Page-based infinite scroll │
│ 🗄️ Caching │ NSCache for avatar images │
│ 💾 Local Storage │ UserDefaults persistence │
│ 🧹 Clean Code │ SOLID, DRY, SRP principles │
│ ♻️ Reusability │ Custom reusable UI components│
│ 🌍 WebView │ In-app WKWebView browser │
│ ⚠️ Error Handling │ Custom GFError enum alerts │
│ 📐 Programmatic UI │ 100% code, zero storyboards │
└──────────────────────┴───────────────────────────────┘
Built on top of URLSession using Swift Concurrency (async/await). A dedicated NetworkManager singleton handles all API calls with clean error propagation via custom GFError enums.
Followers are fetched in pages of 100. The collection view detects when the user nears the bottom and automatically fetches the next page — seamless, no manual "Load More" button.
A shared NSCache instance stores downloaded avatar images keyed by URL string. Repeated visits to the same user never trigger a redundant network request.
The favourites list is encoded as JSON and written to UserDefaults, surviving app restarts. An ergonomic PersistenceManager abstracts all read/write logic away from view controllers.
Custom UIView subclasses (GFButton, GFLabel, GFAvatarImageView, GFEmptyStateView) keep every screen consistent and reduce code duplication to near zero.
A custom GFError enum conforms to Error and covers all failure cases — invalid username, invalid URL, server errors, and decoding failures. Every error maps to a user-friendly message surfaced via a reusable GFAlertVC, so users always know what went wrong without the app ever crashing silently.
- Xcode 15+
- iOS 16.0+
- No third-party dependencies — 100% native Apple frameworks
# Clone the repository
git clone https://github.com/your-username/GitFollow.git
# Open in Xcode
cd GitFollow
open GitFollow.xcodeproj⚡ No CocoaPods, no SPM packages, no setup required. Hit Run and go.
This app uses the GitHub REST API v3 — no authentication required for the endpoints used.
| Endpoint | Usage |
|---|---|
GET /users/{username} |
Fetch user profile details |
GET /users/{username}/followers?page={n}&per_page=100 |
Fetch paginated followers |
Rate limit: 60 requests/hour unauthenticated. Add a personal access token to the
NetworkManagerheaders to increase this to 5,000/hour.
The project follows MVC — the standard UIKit pattern — with a clear separation of concerns:
- Models are plain Swift structs conforming to
Codable - Views are custom
UIView/UIViewControllersubclasses built entirely in code - Controllers delegate business logic to the
NetworkManagerandPersistenceManagersingletons
- Building complex, multi-screen UIKit apps without a single storyboard
- Implementing a robust networking layer with proper error handling
- Using
NSCacheeffectively for performant image loading - Designing a reusable component library that scales across screens
- Making data persistent across app sessions cleanly and safely
- Managing pagination state without blocking the UI thread
Built with 🖤 in Swift
No storyboards were harmed in the making of this app.





