-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
home-view: update homeViewController #49
base: dev-sandra-herrera
Are you sure you want to change the base?
home-view: update homeViewController #49
Conversation
var viewMoreButton = UIButton() | ||
var collectionView: UICollectionView! | ||
|
||
let service = NetworkManager(urlSession: URLSession.shared) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make it private since it's a dependency and inject over init to allow dependency injection
let service = NetworkManager(urlSession: URLSession.shared) | ||
static let categoryHeaderUpcoming = "Upcoming" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make a struct of constants or enums
var movies: [Movie] = [] { | ||
didSet { | ||
collectionView.reloadData() | ||
} | ||
} | ||
|
||
init() { | ||
super.init(collectionViewLayout: HomeViewController.createLayout()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
call a method instead of creating static or Factory pattern can be used here, this just to avoid exposing static elements
static func createLayout() -> UICollectionViewCompositionalLayout { | ||
let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))) | ||
return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection in | ||
if sectionNumber == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No magic numbers, this is risky what if by any reason order change ? wouldn't it be better to use an enum or constant instead ?
let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(200)), subitems: [item]) | ||
item.contentInsets.trailing = 10 | ||
item.contentInsets.leading = 10 | ||
item.contentInsets.bottom = 16 | ||
let section = NSCollectionLayoutSection(group: group) | ||
section.orthogonalScrollingBehavior = .paging | ||
return section | ||
} else { | ||
let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.33), heightDimension: .absolute(150))) | ||
item.contentInsets.trailing = 10 | ||
item.contentInsets.bottom = 5 | ||
let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)), subitems: [item]) | ||
|
||
let section = NSCollectionLayoutSection(group: group) | ||
section.contentInsets.leading = 10 | ||
section.boundarySupplementaryItems = [ | ||
.init(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)), elementKind: categoryHeaderUpcoming, alignment: .topLeading) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can move this into a function
collectionView.register(MovieCell.self, forCellWithReuseIdentifier: "cell") | ||
collectionView.register(HeaderOfSection.self, forSupplementaryViewOfKind: HomeViewController.categoryHeaderUpcoming, withReuseIdentifier: categoryHeaderUpcomingId) | ||
navigationItem.title = "Movies" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this into a method called prepareLayout
or setupLayout
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MovieCell | ||
cell.label?.text = movies[indexPath.row].title | ||
return cell |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid forcewrapping use a guard instead
return cell | ||
} | ||
override func numberOfSections(in collectionView: UICollectionView) -> Int { | ||
2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a magic number, we should know from something how many sections are present sorta like movies var
} | ||
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { | ||
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: categoryHeaderUpcomingId, for: indexPath) as! HeaderOfSection | ||
header.label.text = "Upcoming" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why we create a static element on top and not using it here ?
// | ||
|
||
import Foundation | ||
class MakeRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final
self?.handleResponse(response) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
single space per line
} | ||
let service = NetworkManager(urlSession: URLSession.shared) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
single space per line
|
||
import Foundation | ||
|
||
class GetLatestMoviesRepositoryImpl: GetLatestMoviesRepository{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final
|
||
import Foundation | ||
|
||
class GetLatestMoviesRepositoryImpl: GetLatestMoviesRepository{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class GetLatestMoviesRepositoryImpl: GetLatestMoviesRepository{ | |
class GetLatestMoviesRepositoryImpl: GetLatestMoviesRepository { |
private let basePath: String = URLRequestType.popular.basePath | ||
let service = NetworkManager(urlSession: URLSession.shared) | ||
|
||
func handleResponse(_ response: MovieList) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make it private
func handleResponse(_ response: MovieList) { | |
private func handleResponse(_ response: MovieList) { |
|
||
import Foundation | ||
|
||
class GetNowPlayingMoviesRepositoryImpl: GetNowPlayingMoviesRepository { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fianl
class GetNowPlayingMoviesRepositoryImpl: GetNowPlayingMoviesRepository { | |
final class GetNowPlayingMoviesRepositoryImpl: GetNowPlayingMoviesRepository { |
|
||
func handleResponse(_ response: MovieList) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
func handleResponse(_ response: MovieList) { | |
private func handleResponse(_ response: MovieList) { |
|
||
import Foundation | ||
|
||
class GetPopularMoviesRepositoryImpl: GetPopularMoviesRepository { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class GetPopularMoviesRepositoryImpl: GetPopularMoviesRepository { | |
final class GetPopularMoviesRepositoryImpl: GetPopularMoviesRepository { |
class GetPopularMoviesRepositoryImpl: GetPopularMoviesRepository { | ||
var movies: [Movie] = [] | ||
private let basePath: String = URLRequestType.popular.basePath | ||
let service = NetworkManager(urlSession: URLSession.shared) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let service = NetworkManager(urlSession: URLSession.shared) | |
let service = NetworkManager(urlSession: URLSession.shared) // No singleton should be called here directly |
|
||
import Foundation | ||
|
||
class GetTopRatedMoviesRepositoryImpl: GetListMoviesRepository { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class GetTopRatedMoviesRepositoryImpl: GetListMoviesRepository { | |
final class GetTopRatedMoviesRepositoryImpl: GetListMoviesRepository { |
// | ||
|
||
import Foundation | ||
class GetUpcomingMoviesRepositoryImpl: GetUpcomingMoviesRepository { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class GetUpcomingMoviesRepositoryImpl: GetUpcomingMoviesRepository { | |
final class GetUpcomingMoviesRepositoryImpl: GetUpcomingMoviesRepository { |
} | ||
} | ||
|
||
func handleResponse(_ response: MovieList) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
func handleResponse(_ response: MovieList) { | |
private func handleResponse(_ response: MovieList) { |
// | ||
|
||
import Foundation | ||
class MoviesRepositoryImpl { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class MoviesRepositoryImpl { | |
final class MoviesRepositoryImpl { |
|
||
func requestMovies() { | ||
service.get(path: basePath) { [weak self] response in | ||
_ = self?.handleResponse(response) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can bring a race condition since you are returning values
movies = response.results | ||
} | ||
return movies |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compeltion or return ?
import Foundation | ||
import UIKit | ||
|
||
class HeaderOfSection: UICollectionReusableView { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
final
let label = UILabel() | ||
var title: String? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you really need this cell what about using a default one ?
|
||
override func layoutSubviews() { | ||
super.layoutSubviews() | ||
label.frame = bounds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this line doing ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's focus on some comments related to final, private and accesory levels, we also need to look at DRY principle to avoid repeating code
What does this PR do?
Where should the reviewer start?
Code review checklist Code Review Rubric
DRY Principle (Don’t repeat yourself)
Yagni Principle (You Aren't Gonna Need It)
KISS Principle (Keep It Simple, St...d)
Remove unused code
Hard-coded values
Language style guide & coding conventions
Wizeline Style Guide
RayWenderlich Style Guide
Architecture / Design Pattern
Architecture Implementation
SOLID
Single Responsibility Principle
Open Closed Principle
Liskov substitutability principle
Interface segregation
Dependency Inversion principle
Testing
Force unwrapping !
Mutable vs immutable property (Right use of
let
andvar
)Retain cycles (Capture list)
Code Documentation