10000 fix image loading by glennposadas · Pull Request #3 · sgl0v/TMDB · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix image loading #3

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 8000 service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 9 additions & 22 deletions TMDB/Sources/Screens/Search/MovieTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,19 @@ class MovieTableViewCell: UITableViewCell, NibProvidable, ReusableView {
@IBOutlet private var poster: UIImageView!
private var cancellable: AnyCancellable?

override func prepareForReuse() {
super.prepareForReuse()
cancelImageLoading()
}

func bind(to viewModel: MovieViewModel) {
cancelImageLoading()
title.text = viewModel.title
subtitle.text = viewModel.subtitle
rating.text = viewModel.rating
cancellable = viewModel.poster.sink { [unowned self] image in self.showImage(image: image) }

cancellable = viewModel.poster
.receive(on: DispatchQueue.main)
.assign(to: \.poster.image, on: self)
}

private func showImage(image: UIImage?) {
cancelImageLoading()
UIView.transition(with: self.poster,
duration: 0.3,
options: [.curveEaseOut, .transitionCrossDissolve],
animations: {
self.poster.image = image
})
}

private func cancelImageLoading() {
poster.image = nil
cancellable?.cancel()
}


private func cancelImageLoading() {
poster.image = nil
cancellable?.cancel()
}
}
20 changes: 11 additions & 9 deletions TMDB/Sources/Services/ImageLoader/ImageLoaderService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,23 @@ import UIKit.UIImage
import Combine

final class ImageLoaderService: ImageLoaderServiceType {

private let cache: ImageCacheType = ImageCache()

func loadImage(from url: URL) -> AnyPublisher<UIImage?, Never> {
func loadImage(from url: URL, placeholder: UIImage? = nil) -> AnyPublisher<UIImage?, Never> {
if let image = cache.image(for: url) {
return .just(image)
}
return URLSession.shared.dataTaskPublisher(for: url)
.map { (data, response) -> UIImage? in return UIImage(data: data) }
.catch { error in return Just(nil) }
.handleEvents(receiveOutput: {[unowned self] image in
guard let image = image else { return }
.tryMap { data, response -> UIImage in
guard let image = UIImage(data: data) else {
throw NSError(domain: "", code: 1, userInfo: nil)
}

self.cache.insertImage(image, for: url)
})
.print("Image loading \(url):")
return image
}
.replaceError(with: placeholder)
.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ import UIKit.UIImage
import Combine

protocol ImageLoaderServiceType: AnyObject, AutoMockable {
func loadImage(from url: URL) -> AnyPublisher<UIImage?, Never>
func loadImage(from url: URL, placeholder: UIImage?) -> AnyPublisher<UIImage?, Never>
}
25 changes: 14 additions & 11 deletions TMDB/Sources/UseCases/MoviesUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,19 @@ final class MoviesUseCase: MoviesUseCaseType {
}

func loadImage(for movie: Movie, size: ImageSize) -> AnyPublisher<UIImage?, Never> {
return Deferred { return Just(movie.poster) }
.flatMap({[unowned self] poster -> AnyPublisher<UIImage?, Never> in
guard let poster = movie.poster else { return .just(nil) }
let url = size.url.appendingPathComponent(poster)
return self.imageLoaderService.loadImage(from: url)
})
.subscribe(on: Scheduler.backgroundWorkScheduler)
.receive(on: Scheduler.mainScheduler)
.share()
.eraseToAnyPublisher()
guard let poster = movie.poster else { return .just(nil) }
let url = size.url.appendingPathComponent(poster)
return imageLoaderService.loadImage(from: url, placeholder: imageFrom(color: .gray))
}

func imageFrom(color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor)
context!.fill(rect)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img!
}

}
0