Skip to content

Commit dbca484

Browse files
authored
Merge pull request #24 from engingulek/feature/update-with-concurrency
Feature/update with concurrency
2 parents 4590b69 + 0e7a730 commit dbca484

11 files changed

Lines changed: 101 additions & 160 deletions

.DS_Store

0 Bytes
Binary file not shown.

ICTMDBHomeModule/HomeInteractor.swift

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import Foundation
99
import ICTMDBNetworkManagerKit
1010

1111

12-
final class HomeInteractor: PresenterToInteractorHomeProtocol {
13-
12+
final class HomeInteractor: PresenterToInteractorHomeProtocol,@unchecked Sendable {
13+
1414
// MARK: - Properties
1515

1616
/// Reference to the Presenter to send data or errors back.
17-
var presenter: (any InteractorToPresenterHomeProtocol)?
17+
weak var presenter: (any InteractorToPresenterHomeProtocol)?
1818

1919
/// Network manager responsible for API requests.
2020
private let network: NetworkManagerProtocol
@@ -26,41 +26,20 @@ final class HomeInteractor: PresenterToInteractorHomeProtocol {
2626
self.network = network
2727
}
2828

29-
// MARK: - Popular TV Shows
30-
31-
/// Requests popular TV shows data
32-
func loadPopularMovies() async {
33-
let request = PopularMoviesRequest(
34-
language: deviceLanguageCode == .turkish ? .tr : .en,
35-
page: 1
36-
)
37-
38-
do {
39-
let list = try await network.execute(request)
40-
presenter?.sendPopularTvShows(list.results)
41-
} catch {
42-
presenter?.sendError(.popular)
43-
}
44-
}
45-
46-
47-
48-
// MARK: - Airing Today TV Shows
49-
50-
/// Requests airing today TV shows data
51-
52-
func loadAiringMovies() async {
53-
let request = AiringTodayRequest(
54-
language: deviceLanguageCode == .turkish ? .tr : .en,
55-
page: 1
56-
)
29+
func loadData() async {
30+
let popularMoviesRequest = PopularMoviesRequest(language: deviceLanguageCode == .turkish ? .tr : .en, page: 1)
31+
let airingTodayRequest = AiringTodayRequest(language: deviceLanguageCode == .turkish ? .tr : .en, page: 1)
32+
async let popularMovies = network.execute(popularMoviesRequest)
5733

34+
async let airingMovies = network.execute(airingTodayRequest)
35+
5836
do {
59-
let list = try await network.execute(request)
60-
presenter?.sendAiringTvShows(list.results)
37+
let (popularResult, airingResult) = try await (popularMovies, airingMovies)
38+
39+
await presenter?.sendPopularTvShows(popularResult.results)
40+
await presenter?.sendAiringTvShows(airingResult.results)
6141
} catch {
62-
presenter?.sendError(.airingToday)
63-
42+
await presenter?.sendError()
6443
}
6544
}
6645
}

ICTMDBHomeModule/HomePresenter.swift

Lines changed: 31 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -53,36 +53,24 @@ final class HomePresenter {
5353
/// Handles actions triggered by the View layer.
5454

5555
extension HomePresenter: ViewToPresenterHomeProtocol {
56+
57+
5658

5759
func viewDidLoad() {
5860
view?.setBackColorAble(color: "backColor")
59-
//TODO: move to Localizable
60-
view?.setNavigationTitle(title: "Home Page")
61+
view?.setNavigationTitle(title: LocalizableUI.homePageNavTitle.localized)
6162

6263
Task {@MainActor in
6364
await loadData()
6465
}
65-
66-
6766
}
6867

69-
7068

7169
@MainActor
7270
func loadData() async {
73-
// Sending 'self' risks causing data races
74-
// Sending main actor-isolated 'self' into async let risks causing data races between nonisolated and main actor-isolated uses
75-
76-
/*
77-
async let popular = interactor.loadPopularMovies()
78-
async let movies = interactor.loadAiringMovies()
79-
await popular
80-
await movies
81-
*/
82-
83-
84-
await interactor.loadPopularMovies()
85-
await interactor.loadAiringMovies()
71+
view?.startLoading()
72+
await interactor.loadData()
73+
view?.finishLoading()
8674
}
8775

8876
}
@@ -142,33 +130,28 @@ extension HomePresenter {
142130
}
143131
}
144132

145-
146-
func titleForSection(at section: Int) -> (
147-
title: String,
148-
sizeType: SectionSizeType,
149-
buttonType: [TitleForSectionButtonType]?
150-
) {
133+
func titleForSection(at section: Int) -> GenericCollectionViewKit.HeaderViewItem {
134+
var headerViewItem:HeaderViewItem
151135
guard let sectionType = SectionType(rawValue: section) else {
152-
return (title: "", sizeType: .small, buttonType: [])
136+
headerViewItem = .init(title: "", sizeType: .empty)
137+
return headerViewItem
153138
}
154139

155-
var item: (title: String, sizeType: SectionSizeType, buttonType: [TitleForSectionButtonType]?)
156-
157140
switch sectionType {
158141
case .popular:
159-
item = (
142+
headerViewItem = .init(
160143
title: LocalizableUI.popular.localized,
144+
icon: .init(image: .systemImage("flame.fill"), tintColor: .custom(hex: "#FF0000")),
161145
sizeType: .large,
162-
buttonType: [.allList]
163-
)
146+
buttonTypes: [.allList])
164147
case .airingToday:
165-
item = (
148+
headerViewItem = .init(
166149
title: LocalizableUI.airingToday.localized,
167-
sizeType: .small,
168-
buttonType: [.allList]
169-
)
150+
icon: .init(image: .systemImage("circle.fill"), tintColor: .custom(hex: "#008000")),
151+
sizeType: .large,
152+
buttonTypes: [.allList])
170153
}
171-
return item
154+
return headerViewItem
172155
}
173156

174157

@@ -210,32 +193,32 @@ extension HomePresenter {
210193

211194
// MARK: - InteractorToPresenterHomeProtocol
212195
/// Receives data from the Interactor and updates the view.
213-
extension HomePresenter: InteractorToPresenterHomeProtocol {
196+
extension HomePresenter: InteractorToPresenterHomeProtocol {
197+
func sendError() {
198+
199+
view?.sendError(errorState: (isHidden: true,
200+
message: LocalizableUI.somethingWentWrong.localized))
201+
view?.relaodCollectionView()
202+
203+
}
204+
214205

215206
func sendAiringTvShows(_ data: [AiringToday]) {
216-
view?.startLoading()
207+
217208
airingTodayShows = data.map { AiringTodayPresentation(tvShow: $0) }
218209
view?.sendError(errorState: (isHidden: false, message: ""))
219210
view?.relaodCollectionView()
220-
view?.finishLoading()
211+
221212
}
222213

223214
func sendPopularTvShows(_ data: [PopularTvShows]) {
224-
view?.startLoading()
215+
225216
popularTvShows = data
226217
.map { PopularTVShowPresentation(tvShow: $0) }
227218
.sorted { $0.rating > $1.rating }
228219
view?.sendError(errorState: (isHidden: false, message: ""))
229220
view?.relaodCollectionView()
230-
view?.finishLoading()
231-
}
232-
233-
func sendError(_ type: HomePageErrorType) {
234-
view?.startLoading()
235-
view?.sendError(errorState: (isHidden: true,
236-
message: LocalizableUI.somethingWentWrong.localized))
237-
view?.relaodCollectionView()
238-
view?.finishLoading()
221+
239222
}
240223
}
241224

ICTMDBHomeModule/HomeProtocols.swift

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,20 @@ protocol PresenterToViewHomeProtocol: AnyObject, Ables {
5050

5151
// MARK: - Presenter → Interactor
5252
/// Protocol defining communication from Presenter to Interactor.
53-
@MainActor
54-
protocol PresenterToInteractorHomeProtocol:AnyObject {
53+
54+
protocol PresenterToInteractorHomeProtocol:Sendable,AnyObject {
5555

5656
/// Reference to the Presenter layer
5757
var presenter: InteractorToPresenterHomeProtocol? { get set }
58-
59-
/// Requests popular TV shows data
60-
func loadPopularMovies() async
61-
62-
/// Requests airing today TV shows data
63-
func loadAiringMovies() async
58+
59+
// Requests data
60+
func loadData() async
6461
}
6562

6663

6764
// MARK: - Interactor → Presenter
6865
/// Protocol for sending data or errors from Interactor to Presenter.
66+
@MainActor
6967
protocol InteractorToPresenterHomeProtocol : AnyObject{
7068

7169
/// Sends fetched popular TV shows
@@ -75,7 +73,8 @@ protocol InteractorToPresenterHomeProtocol : AnyObject{
7573
func sendAiringTvShows(_ data: [AiringToday])
7674

7775
/// Sends an error state
78-
func sendError(_ type: HomePageErrorType)
76+
func sendError()
77+
7978
}
8079

8180
// MARK: - Presenter → Router

ICTMDBHomeModule/HomeRouter.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,8 @@ public class HomeRouter: PresenterToRouterHomeProtocol {
4444

4545
func toDetailPage(view: (any PresenterToViewHomeProtocol)?, id: Int?) {
4646
// Resolve Detail module dependency from DependencyRegister
47-
// Detail modülünü DependencyRegister üzerinden alır
4847
let detailModule = DependencyRegister.shared.resolve(TvShowDetailProtocol.self)
49-
5048
// Create the Detail view controller using module
51-
// Modül üzerinden Detail view controller oluşturur
5249
let detailViewController = detailModule.createTvShowDetailModule(id: id)
5350

5451
view?.pushViewControllerAble(detailViewController, animated: true)

ICTMDBHomeModule/HomeViewController.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,5 +136,6 @@ extension HomeViewController: @MainActor PresenterToViewHomeProtocol {
136136
// MARK: - Preview
137137
#Preview {
138138
let module = ICTMDBHomeModule()
139-
UINavigationController(rootViewController: module.createHomeModule())
139+
140+
return UINavigationController(rootViewController: module.createHomeModule())
140141
}

0 commit comments

Comments
 (0)