From b57d40e277718556a59c4b300bf19825bcc23f8d Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sat, 16 Mar 2024 03:03:22 +0100 Subject: [PATCH 1/9] Fixed the reference to the Libraries test plan for the schemes in the project. --- Reviews.xcodeproj/project.pbxproj | 10 +++++----- .../Libraries.xctestplan | 0 2 files changed, 5 insertions(+), 5 deletions(-) rename Libraries.xctestplan => Test Plans/Libraries.xctestplan (100%) diff --git a/Reviews.xcodeproj/project.pbxproj b/Reviews.xcodeproj/project.pbxproj index 4feecf0..822b22a 100644 --- a/Reviews.xcodeproj/project.pbxproj +++ b/Reviews.xcodeproj/project.pbxproj @@ -46,7 +46,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 02900C492BA530E6008D2E8D /* Libraries.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Libraries.xctestplan; sourceTree = ""; }; + 02900C4B2BA5347A008D2E8D /* Libraries.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Libraries.xctestplan; sourceTree = ""; }; 02DC7F8F2BA51793000EEEBE /* ReviewsFeed.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReviewsFeed.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 02DC7F912BA51793000EEEBE /* ReviewsFeed.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReviewsFeed.h; sourceTree = ""; }; 02DC7FB12BA52084000EEEBE /* Libraries */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Libraries; sourceTree = ""; }; @@ -82,12 +82,12 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 02900C4A2BA53162008D2E8D /* Test Plans */ = { + 02900C4C2BA5347A008D2E8D /* Test Plans */ = { isa = PBXGroup; children = ( - 02900C492BA530E6008D2E8D /* Libraries.xctestplan */, + 02900C4B2BA5347A008D2E8D /* Libraries.xctestplan */, ); - name = "Test Plans"; + path = "Test Plans"; sourceTree = ""; }; 02DC7F722BA4F8F0000EEEBE /* Resources */ = { @@ -166,7 +166,7 @@ 02DC7FB12BA52084000EEEBE /* Libraries */, 02DC7FAB2BA51848000EEEBE /* Frameworks */, 345AD11A24C6EDD9004E2EE1 /* App */, - 02900C4A2BA53162008D2E8D /* Test Plans */, + 02900C4C2BA5347A008D2E8D /* Test Plans */, 345AD11924C6EDD9004E2EE1 /* Products */, ); sourceTree = ""; diff --git a/Libraries.xctestplan b/Test Plans/Libraries.xctestplan similarity index 100% rename from Libraries.xctestplan rename to Test Plans/Libraries.xctestplan -- 2.47.1 From 6d6de392b32cf4fd978faf6e4f47120f9d241763 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sat, 16 Mar 2024 03:06:57 +0100 Subject: [PATCH 2/9] Created the API library in the Libraries package. --- Libraries/Package.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Libraries/Package.swift b/Libraries/Package.swift index 2fa99db..1746f4f 100644 --- a/Libraries/Package.swift +++ b/Libraries/Package.swift @@ -11,15 +11,27 @@ let package = Package( .library( name: .Product.name.kit, targets: [ + .Target.api, .Target.foundation ] ), ], targets: [ + .target( + name: .Target.api, + path: "API/Kit" + ), .target( name: .Target.foundation, path: "Foundation/Kit" ), + .testTarget( + name: .Target.api.test, + dependencies: [ + .byName(name: .Target.api) + ], + path: "API/Test" + ), .testTarget( name: .Target.foundation.test, dependencies: [ @@ -41,6 +53,7 @@ private extension String { } enum Target { + static let api = "\(String.Product.name)API" static let foundation = "\(String.Product.name)Foundation" } } -- 2.47.1 From 8f279d203428260fa6ad228d3a1bf03c933d112a Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sat, 16 Mar 2024 09:40:16 +0100 Subject: [PATCH 3/9] Moved the existing files under the Feed framework to its "Bundle" folder. --- Frameworks/Feed/{ => Bundle}/ReviewsFeed.h | 0 .../Sources/DetailsViewController.swift | 0 .../Sources/FeedViewController.swift | 0 .../Feed/{ => Bundle}/Sources/Review.swift | 0 .../{ => Bundle}/Sources/ReviewCell.swift | 0 Reviews.xcodeproj/project.pbxproj | 20 +++++++++++++++++-- 6 files changed, 18 insertions(+), 2 deletions(-) rename Frameworks/Feed/{ => Bundle}/ReviewsFeed.h (100%) rename Frameworks/Feed/{ => Bundle}/Sources/DetailsViewController.swift (100%) rename Frameworks/Feed/{ => Bundle}/Sources/FeedViewController.swift (100%) rename Frameworks/Feed/{ => Bundle}/Sources/Review.swift (100%) rename Frameworks/Feed/{ => Bundle}/Sources/ReviewCell.swift (100%) diff --git a/Frameworks/Feed/ReviewsFeed.h b/Frameworks/Feed/Bundle/ReviewsFeed.h similarity index 100% rename from Frameworks/Feed/ReviewsFeed.h rename to Frameworks/Feed/Bundle/ReviewsFeed.h diff --git a/Frameworks/Feed/Sources/DetailsViewController.swift b/Frameworks/Feed/Bundle/Sources/DetailsViewController.swift similarity index 100% rename from Frameworks/Feed/Sources/DetailsViewController.swift rename to Frameworks/Feed/Bundle/Sources/DetailsViewController.swift diff --git a/Frameworks/Feed/Sources/FeedViewController.swift b/Frameworks/Feed/Bundle/Sources/FeedViewController.swift similarity index 100% rename from Frameworks/Feed/Sources/FeedViewController.swift rename to Frameworks/Feed/Bundle/Sources/FeedViewController.swift diff --git a/Frameworks/Feed/Sources/Review.swift b/Frameworks/Feed/Bundle/Sources/Review.swift similarity index 100% rename from Frameworks/Feed/Sources/Review.swift rename to Frameworks/Feed/Bundle/Sources/Review.swift diff --git a/Frameworks/Feed/Sources/ReviewCell.swift b/Frameworks/Feed/Bundle/Sources/ReviewCell.swift similarity index 100% rename from Frameworks/Feed/Sources/ReviewCell.swift rename to Frameworks/Feed/Bundle/Sources/ReviewCell.swift diff --git a/Reviews.xcodeproj/project.pbxproj b/Reviews.xcodeproj/project.pbxproj index 822b22a..22420ed 100644 --- a/Reviews.xcodeproj/project.pbxproj +++ b/Reviews.xcodeproj/project.pbxproj @@ -90,6 +90,22 @@ path = "Test Plans"; sourceTree = ""; }; + 02A6DA2F2BA591C000B943E2 /* Bundle */ = { + isa = PBXGroup; + children = ( + 02DC7F912BA51793000EEEBE /* ReviewsFeed.h */, + 02DC7FB02BA51B4F000EEEBE /* Sources */, + ); + path = Bundle; + sourceTree = ""; + }; + 02A6DA302BA5929F00B943E2 /* Test */ = { + isa = PBXGroup; + children = ( + ); + path = Test; + sourceTree = ""; + }; 02DC7F722BA4F8F0000EEEBE /* Resources */ = { isa = PBXGroup; children = ( @@ -135,8 +151,8 @@ 02DC7F902BA51793000EEEBE /* Feed */ = { isa = PBXGroup; children = ( - 02DC7F912BA51793000EEEBE /* ReviewsFeed.h */, - 02DC7FB02BA51B4F000EEEBE /* Sources */, + 02A6DA2F2BA591C000B943E2 /* Bundle */, + 02A6DA302BA5929F00B943E2 /* Test */, ); path = Feed; sourceTree = ""; -- 2.47.1 From 8dacbfd51d31a2f96909c05d65dceb37fe6121a6 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sun, 17 Mar 2024 15:53:08 +0100 Subject: [PATCH 4/9] Created the Feed and iTunes libraries in the Libraries package. --- Libraries/Package.swift | 42 ++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/Libraries/Package.swift b/Libraries/Package.swift index 1746f4f..25f97f7 100644 --- a/Libraries/Package.swift +++ b/Libraries/Package.swift @@ -11,34 +11,53 @@ let package = Package( .library( name: .Product.name.kit, targets: [ - .Target.api, - .Target.foundation + .Target.feed.kit, + .Target.foundation.kit, + .Target.iTunes.kit, ] ), ], targets: [ .target( - name: .Target.api, - path: "API/Kit" + name: .Target.feed.kit, + dependencies: [ + .byName(name: .Target.foundation.kit), + ], + path: "Feed/Kit" ), .target( - name: .Target.foundation, + name: .Target.foundation.kit, path: "Foundation/Kit" ), - .testTarget( - name: .Target.api.test, + .target( + name: .Target.iTunes.kit, dependencies: [ - .byName(name: .Target.api) + .byName(name: .Target.feed.kit), + .byName(name: .Target.foundation.kit), ], - path: "API/Test" + path: "iTunes/Kit" + ), + .testTarget( + name: .Target.feed.test, + dependencies: [ + .byName(name: .Target.feed.kit), + ], + path: "Feed/Test" ), .testTarget( name: .Target.foundation.test, dependencies: [ - .byName(name: .Target.foundation) + .byName(name: .Target.foundation.kit), ], path: "Foundation/Test" ), + .testTarget( + name: .Target.iTunes.test, + dependencies: [ + .byName(name: .Target.iTunes.kit), + ], + path: "iTunes/Test" + ), ] ) @@ -53,8 +72,9 @@ private extension String { } enum Target { - static let api = "\(String.Product.name)API" + static let feed = "\(String.Product.name)Feed" static let foundation = "\(String.Product.name)Foundation" + static let iTunes = "\(String.Product.name)iTunes" } } -- 2.47.1 From 6245e87a983d7aa0f0b7eb3484fbeb78556cf33c Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sun, 17 Mar 2024 16:07:08 +0100 Subject: [PATCH 5/9] Defined the Endpoint protocol in the Feed library. --- .../Feed/Kit/Sources/Protocols/Endpoint.swift | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Libraries/Feed/Kit/Sources/Protocols/Endpoint.swift diff --git a/Libraries/Feed/Kit/Sources/Protocols/Endpoint.swift b/Libraries/Feed/Kit/Sources/Protocols/Endpoint.swift new file mode 100644 index 0000000..44f59f2 --- /dev/null +++ b/Libraries/Feed/Kit/Sources/Protocols/Endpoint.swift @@ -0,0 +1,32 @@ +// +// Endpoint.swift +// ReviewsFeedKit +// +// Created by Javier Cicchelli on 17/03/2024. +// Copyright © 2024 Röck+Cöde VoF. All rights reserved. +// + +import Foundation + +public protocol Endpoint { + + // MARK: Associated types + associatedtype Input: EndpointInput + associatedtype Output: EndpointOutput + + // MARK: Properties + var host: URL { get } + var decoder: JSONDecoder { get } + var session: URLSession { get } + + // MARK: Functions + func callAsFunction(_ input: Input) async throws -> Output + func makePath(with input: Input) throws -> String + +} + +// MARK: - Input +public protocol EndpointInput {} + +// MARK: - Output +public protocol EndpointOutput {} -- 2.47.1 From 7a7df4cfeaac3ef85283c517678740ca35ccd714 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sun, 17 Mar 2024 16:08:18 +0100 Subject: [PATCH 6/9] Implemented the Review model in the Feed library. --- .../Feed/Kit/Sources/Models/Review.swift | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Libraries/Feed/Kit/Sources/Models/Review.swift diff --git a/Libraries/Feed/Kit/Sources/Models/Review.swift b/Libraries/Feed/Kit/Sources/Models/Review.swift new file mode 100644 index 0000000..90b511e --- /dev/null +++ b/Libraries/Feed/Kit/Sources/Models/Review.swift @@ -0,0 +1,41 @@ +// +// Review.swift +// ReviewsFeedKit +// +// Created by Javier Cicchelli on 17/03/2024. +// Copyright © 2024 Röck+Cöde VoF. All rights reserved. +// + +import Foundation + +public struct Review { + + // MARK: Constants + public let author: String + public let content: String + public let id: Int + public let rating: Int + public let title: String + public let updated: Date + public let version: String + + // MARK: Initialisers + public init( + id: Int, + author: String, + title: String, + content: String, + rating: Int, + version: String, + updated: Date + ) { + self.author = author + self.content = content + self.id = id + self.rating = rating + self.title = title + self.updated = updated + self.version = version + } + +} -- 2.47.1 From 93a52fd93e744c7909cd275bb4f8e67903367649 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sun, 17 Mar 2024 16:08:51 +0100 Subject: [PATCH 7/9] Defined the GetReviewsEndpoint protocol in the Feed library. --- .../Endpoints/GetReviewsEndpoint.swift | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Libraries/Feed/Kit/Sources/Protocols/Endpoints/GetReviewsEndpoint.swift diff --git a/Libraries/Feed/Kit/Sources/Protocols/Endpoints/GetReviewsEndpoint.swift b/Libraries/Feed/Kit/Sources/Protocols/Endpoints/GetReviewsEndpoint.swift new file mode 100644 index 0000000..0159e5e --- /dev/null +++ b/Libraries/Feed/Kit/Sources/Protocols/Endpoints/GetReviewsEndpoint.swift @@ -0,0 +1,44 @@ +// +// GetReviewsEndpoint.swift +// ReviewsFeedKit +// +// Created by Javier Cicchelli on 17/03/2024. +// Copyright © 2024 Röck+Cöde VoF. All rights reserved. +// + +import Foundation + +public protocol GetReviewsEndpoint: Endpoint +where Input == GetReviewsInput, + Output == GetReviewsOutput {} + +// MARK: - Input +public struct GetReviewsInput: EndpointInput { + + // MARK: Constants + public let appID: String + public let countryCode: String + + // MARK: Initialisers + public init( + appID: String, + countryCode: String + ) { + self.appID = appID + self.countryCode = countryCode + } + +} + +// MARK: - Output +public struct GetReviewsOutput: EndpointOutput { + + // MARK: Constants + public let reviews: [Review] + + // MARK: Initialisers + public init(reviews: [Review]) { + self.reviews = reviews + } + +} -- 2.47.1 From f97025fdb82c2accb6c061a0e86c758d7eb7bde7 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sun, 17 Mar 2024 16:09:13 +0100 Subject: [PATCH 8/9] Defined the EndpointError error in the Feed library. --- .../Feed/Kit/Sources/Errors/EndpointError.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Libraries/Feed/Kit/Sources/Errors/EndpointError.swift diff --git a/Libraries/Feed/Kit/Sources/Errors/EndpointError.swift b/Libraries/Feed/Kit/Sources/Errors/EndpointError.swift new file mode 100644 index 0000000..d8e4249 --- /dev/null +++ b/Libraries/Feed/Kit/Sources/Errors/EndpointError.swift @@ -0,0 +1,13 @@ +// +// EndpointError.swift +// ReviewsFeedKit +// +// Created by Javier Cicchelli on 17/03/2024. +// Copyright © 2024 Röck+Cöde VoF. All rights reserved. +// + +public enum EndpointError: Error { + case inputParametersEmpty + case requestFailed(statusCode: Int) + case responseNotFound +} -- 2.47.1 From 7beb36068b32a34c90444bc636b9b5b2a73d63e1 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sun, 17 Mar 2024 16:10:13 +0100 Subject: [PATCH 9/9] Defined the Service protocol in the Feed library. --- .../Feed/Kit/Sources/Protocols/Service.swift | 21 ++++++++++++++ .../Structs/ServiceConfiguration.swift | 29 +++++++++++++++++++ .../Sources/Extensions/String+Constants.swift | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 Libraries/Feed/Kit/Sources/Protocols/Service.swift create mode 100644 Libraries/Feed/Kit/Sources/Structs/ServiceConfiguration.swift diff --git a/Libraries/Feed/Kit/Sources/Protocols/Service.swift b/Libraries/Feed/Kit/Sources/Protocols/Service.swift new file mode 100644 index 0000000..d602442 --- /dev/null +++ b/Libraries/Feed/Kit/Sources/Protocols/Service.swift @@ -0,0 +1,21 @@ +// +// Service.swift +// ReviewsFeedKit +// +// Created by Javier Cicchelli on 17/03/2024. +// Copyright © 2024 Röck+Cöde VoF. All rights reserved. +// + +import Foundation + +public protocol Service { + + // MARK: Properties + var configuration: ServiceConfiguration { get } + var decoder: JSONDecoder { get } + var session: URLSession { get } + + // MARK: Functions + func getReviews(_ input: GetReviewsInput) async throws -> GetReviewsOutput + +} diff --git a/Libraries/Feed/Kit/Sources/Structs/ServiceConfiguration.swift b/Libraries/Feed/Kit/Sources/Structs/ServiceConfiguration.swift new file mode 100644 index 0000000..32df28f --- /dev/null +++ b/Libraries/Feed/Kit/Sources/Structs/ServiceConfiguration.swift @@ -0,0 +1,29 @@ +// +// ServiceConfiguration.swift +// ReviewsiTunesKit +// +// Created by Javier Cicchelli on 17/03/2024. +// Copyright © 2024 Röck+Cöde VoF. All rights reserved. +// + +import Foundation + +public struct ServiceConfiguration { + + // MARK: Constants + public let decoder: JSONDecoder + public let host: URL + public let session: URLSessionConfiguration + + // MARK: Initialisers + public init( + host: URL, + session: URLSessionConfiguration = .ephemeral, + decoder: JSONDecoder? = nil + ) { + self.decoder = decoder ?? .init() + self.host = host + self.session = session + } + +} diff --git a/Libraries/Foundation/Kit/Sources/Extensions/String+Constants.swift b/Libraries/Foundation/Kit/Sources/Extensions/String+Constants.swift index ab80392..f6d84ec 100644 --- a/Libraries/Foundation/Kit/Sources/Extensions/String+Constants.swift +++ b/Libraries/Foundation/Kit/Sources/Extensions/String+Constants.swift @@ -1,6 +1,6 @@ // // String+Constants.swift -// ReviewsFoundation +// ReviewsFoundationKit // // Created by Javier Cicchelli on 16/03/2024. // Copyright © 2024 Röck+Cöde VoF. All rights reserved. -- 2.47.1