Skip to content

mdolancode/Anime-Quotes

Repository files navigation

Anime Quotes

An iOS app that fetches and displays random anime quotes — built for anime lovers who want a fresh quote every time they open the app or pull to refresh. Originally published on the App Store in 2021, and actively developed through 2025 with a full architectural overhaul. No longer available following developer account closure.

Tech Stack: Swift, UIKit, async/await, URLSession, Coordinators, Codable, UITabBarController, UserDefaults, Accessibility


What Changed (2024–2025)

The app was significantly rebuilt after the initial 1.0 release:

  • Migrated from Alamofire to URLSession + async/await — removed the third-party dependency and rewrote the networking layer using Swift Concurrency
  • Updated API — adapted to a new API response format (animechan.io v1), requiring a new model layer (AnimeResponse, AnimeQuoteData, AnimeInfo, CharacterInfo) that maps to the original AnimeDataModel
  • Daily quote cachingNetworkService uses UserDefaults to persist the day's quote, so the same quote shows throughout the day and a new one is fetched the next
  • QuoteService abstraction — introduced a service layer to route between free and premium API endpoints, keeping networking logic out of the view controller
  • Settings screen — built a full SettingsVC with a programmatic grouped UITableView, three custom cell types (SwitchCell, ButtonCell, InfoCell), and a data-driven section model. Includes premium API toggle, dark mode toggle (premium-gated), upgrade flow, privacy policy, and live app version display
  • Tab bar architecture — refactored from a single-screen coordinator to a full UITabBarController with three tabs (Quotes, Shout Outs, Settings), each with its own coordinator and navigation controller
  • AppearanceManager — centralized global UI styling (tab bar transparency, tint colour, translucency) into a singleton, keeping appearance logic out of AppDelegate
  • Error handling — added a typed NetworkError enum (invalidURL, noData, decodingError) with user-facing alerts and a Retry action
  • BundleExtension — version string utility reading CFBundleShortVersionString and CFBundleVersion, with environment scheme detection for dev/staging builds

Features

  • Random anime quotes fetched on launch and pull-to-refresh
  • Daily quote caching — same quote shown throughout the day, new quote on next day
  • Settings screen with premium toggle, dark mode toggle, upgrade flow, and privacy policy
  • Three-tab navigation: Quotes, Shout Outs, Settings
  • Shout Outs screen credits the API creator and photographer with tappable SafariServices links
  • VoiceOver accessibility support including the Z gesture to dismiss the Shout Outs screen
  • Typed error handling with user-facing retry alerts
  • SwiftLint configured throughout

Architecture

App
├── AppCoordinator               — root coordinator, sets up UITabBarController
├── AnimeQuotesTabCoordinator
│   └── AnimeQuotesVC            — fetches quotes via QuoteService, renders in UITableView
├── ShoutOutsTabCoordinator
│   └── ShoutOutsVC              — credits screen with SafariServices + VoiceOver Z gesture
├── SettingsTabCoordinator
│   └── SettingsVC               — programmatic grouped UITableView with custom cells
│
├── QuoteService                 — routes to free or premium endpoint based on UserDefaults
├── NetworkService               — URLSession + async/await, daily caching via UserDefaults
├── AppearanceManager            — global tab bar and UI styling singleton
└── BundleExtension              — version string utility with environment detection

Technical Highlights

  • async/await networking — migrated away from Alamofire to native Swift Concurrency; fetchData() uses URLSession.shared.data(from:) with structured error propagation
  • API versioning — when the upstream API changed its response shape, a new nested model layer was introduced to decode the new format while preserving the existing AnimeDataModel used throughout the UI
  • Data-driven SettingsSettingsSection / SettingsItem models drive the entire settings table; adding a new row is a one-line change to the section array
  • Coordinator memory managementchildDidFinish(_:) cleans up child coordinators on back navigation via UINavigationControllerDelegate
  • Per-tab coordinators — each tab owns its own UINavigationController and coordinator, keeping navigation logic fully isolated between screens

Screenshots

Launch Screen

Anime Quotes launch screen.

Quotes Screen

Anime Quotes screen displaying quotes.

Shout Outs Screen

Shout Outs screen.


License

MIT — feel free to use this project, but please change the UI (colours, fonts, images, layout) if redistributing.

About

A UIKit iOS app displaying random anime quotes — migrated to async/await, rebuilt with a tab bar, Settings screen, daily quote caching, and typed error handling. Previously published on the App Store.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages