Skip to content

Lainaaa/Accedo-Test-Assignment

Repository files navigation

Accedo Test Assignment

Notes

  • Instead of UserDefaults for caching, any other framework could be used thanks to the protocol-oriented approach. UserDefaults was chosen only for its simplicity.
  • It would be beneficial to introduce Dependency Injection (e.g., Swiftject or Needle) for more flexible dependency management.
  • SwiftUI was selected because it was explicitly mentioned in the job requirements, however, I also have experience working with UIKit.
  • The Config folder should contain the Secrets.swift file, which holds the API keys and tokens (ignored in git, with a Secrets.sample.swift template included).

Demo videos: tvOS demo is available here, and the iOS demo is available here.

Demo Overview

  • Genres screen: cached for 1 hour locally; tap a genre to open the movie grid
  • Movies screen: grid with posters + titles, infinite scrolling with prefetching
  • Image loading via AsyncImage (TMDB w200 image base)
  • Clean MVVM structure with protocol-based services
  • tvOS target that reuses the same SwiftUI code

Requirements Coverage

  • Genres screen: Done
  • Navigate to movies on genre tap: Done (NavigationStack + Router)
  • Data from TMDB: Done (themoviedb.org v3 API)
  • Genres cache: Done (UserDefaults TTL = 1 hour)
  • Movies pagination: Done (load-more prefetch; threshold-based)
  • Bonus – Grid: Done (2 columns on iPhone, 4 on tablet)
  • Bonus – tvOS support: Done (separate tvOS target, shared sources)

Tech Stack

  • Swift 6, SwiftUI, Concurrency (async/await)
  • Xcode 16.3+
  • iOS 18.0+, tvOS 18.0+
  • Alamofire (SPM)

Architecture

  • Pattern: MVVM with a state
  • Networking: Request protocol + NetworkService.execute<R: Request>(R) async
  • Services:
    • TMDBService: domain-specific client built on NetworkService
    • CacheService: UserDefaults-based genre cache with 1-hour TTL
  • Views: SwiftUI screens bound to view models with @StateObject
  • Router: simple enum-based router injected via environment

Data Flow

  1. GenresViewModel loads genres
    • Checks CacheService.isGenresCacheValid() and loadGenres() first
    • If invalid/missing, requests TMDBService.fetchGenres() then saveGenres()
  2. Tap a genre -> Router pushes MoviesView
  3. MoviesViewModel loads first page via TMDBService.discoverMovies(genreId:page:)
    • Keeps page/totalPages and appends unique movies while paginating
    • Triggers loadMoreIfNeeded near the end via onAppear threshold

Future Enhancements

  • Unit tests for GenresViewModel and MoviesViewModel (loading, cache hit/miss, pagination, error handling)
  • tvOS improvments
  • Pull-to-refresh and manual retry on movies list
  • Image caching (e.g., via Nuke/Kingfisher or URLCache tuning)
  • Error handling improvements

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages