[Library] Feed library (#4)
This PR contains the work done to setup the library and also, the necessary protocols, model, structs, and error definitions to implement remote service clients. Reviewed-on: #4 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit is contained in:
parent
8fa5533426
commit
4359f53a19
13
Libraries/Feed/Kit/Sources/Errors/EndpointError.swift
Normal file
13
Libraries/Feed/Kit/Sources/Errors/EndpointError.swift
Normal file
@ -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
|
||||||
|
}
|
41
Libraries/Feed/Kit/Sources/Models/Review.swift
Normal file
41
Libraries/Feed/Kit/Sources/Models/Review.swift
Normal file
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
Libraries/Feed/Kit/Sources/Protocols/Endpoint.swift
Normal file
32
Libraries/Feed/Kit/Sources/Protocols/Endpoint.swift
Normal file
@ -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 {}
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
Libraries/Feed/Kit/Sources/Protocols/Service.swift
Normal file
21
Libraries/Feed/Kit/Sources/Protocols/Service.swift
Normal file
@ -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
|
||||||
|
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// String+Constants.swift
|
// String+Constants.swift
|
||||||
// ReviewsFoundation
|
// ReviewsFoundationKit
|
||||||
//
|
//
|
||||||
// Created by Javier Cicchelli on 16/03/2024.
|
// Created by Javier Cicchelli on 16/03/2024.
|
||||||
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
|
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
|
||||||
|
@ -11,22 +11,53 @@ let package = Package(
|
|||||||
.library(
|
.library(
|
||||||
name: .Product.name.kit,
|
name: .Product.name.kit,
|
||||||
targets: [
|
targets: [
|
||||||
.Target.foundation
|
.Target.feed.kit,
|
||||||
|
.Target.foundation.kit,
|
||||||
|
.Target.iTunes.kit,
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
name: .Target.foundation,
|
name: .Target.feed.kit,
|
||||||
|
dependencies: [
|
||||||
|
.byName(name: .Target.foundation.kit),
|
||||||
|
],
|
||||||
|
path: "Feed/Kit"
|
||||||
|
),
|
||||||
|
.target(
|
||||||
|
name: .Target.foundation.kit,
|
||||||
path: "Foundation/Kit"
|
path: "Foundation/Kit"
|
||||||
),
|
),
|
||||||
|
.target(
|
||||||
|
name: .Target.iTunes.kit,
|
||||||
|
dependencies: [
|
||||||
|
.byName(name: .Target.feed.kit),
|
||||||
|
.byName(name: .Target.foundation.kit),
|
||||||
|
],
|
||||||
|
path: "iTunes/Kit"
|
||||||
|
),
|
||||||
|
.testTarget(
|
||||||
|
name: .Target.feed.test,
|
||||||
|
dependencies: [
|
||||||
|
.byName(name: .Target.feed.kit),
|
||||||
|
],
|
||||||
|
path: "Feed/Test"
|
||||||
|
),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: .Target.foundation.test,
|
name: .Target.foundation.test,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.byName(name: .Target.foundation)
|
.byName(name: .Target.foundation.kit),
|
||||||
],
|
],
|
||||||
path: "Foundation/Test"
|
path: "Foundation/Test"
|
||||||
),
|
),
|
||||||
|
.testTarget(
|
||||||
|
name: .Target.iTunes.test,
|
||||||
|
dependencies: [
|
||||||
|
.byName(name: .Target.iTunes.kit),
|
||||||
|
],
|
||||||
|
path: "iTunes/Test"
|
||||||
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,7 +72,9 @@ private extension String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum Target {
|
enum Target {
|
||||||
|
static let feed = "\(String.Product.name)Feed"
|
||||||
static let foundation = "\(String.Product.name)Foundation"
|
static let foundation = "\(String.Product.name)Foundation"
|
||||||
|
static let iTunes = "\(String.Product.name)iTunes"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
02900C492BA530E6008D2E8D /* Libraries.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Libraries.xctestplan; sourceTree = "<group>"; };
|
02900C4B2BA5347A008D2E8D /* Libraries.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Libraries.xctestplan; sourceTree = "<group>"; };
|
||||||
02DC7F8F2BA51793000EEEBE /* ReviewsFeed.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReviewsFeed.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
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 = "<group>"; };
|
02DC7F912BA51793000EEEBE /* ReviewsFeed.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReviewsFeed.h; sourceTree = "<group>"; };
|
||||||
02DC7FB12BA52084000EEEBE /* Libraries */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Libraries; sourceTree = "<group>"; };
|
02DC7FB12BA52084000EEEBE /* Libraries */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Libraries; sourceTree = "<group>"; };
|
||||||
@ -82,12 +82,28 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
02900C4A2BA53162008D2E8D /* Test Plans */ = {
|
02900C4C2BA5347A008D2E8D /* Test Plans */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
02900C492BA530E6008D2E8D /* Libraries.xctestplan */,
|
02900C4B2BA5347A008D2E8D /* Libraries.xctestplan */,
|
||||||
);
|
);
|
||||||
name = "Test Plans";
|
path = "Test Plans";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
02A6DA2F2BA591C000B943E2 /* Bundle */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
02DC7F912BA51793000EEEBE /* ReviewsFeed.h */,
|
||||||
|
02DC7FB02BA51B4F000EEEBE /* Sources */,
|
||||||
|
);
|
||||||
|
path = Bundle;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
02A6DA302BA5929F00B943E2 /* Test */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
);
|
||||||
|
path = Test;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
02DC7F722BA4F8F0000EEEBE /* Resources */ = {
|
02DC7F722BA4F8F0000EEEBE /* Resources */ = {
|
||||||
@ -135,8 +151,8 @@
|
|||||||
02DC7F902BA51793000EEEBE /* Feed */ = {
|
02DC7F902BA51793000EEEBE /* Feed */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
02DC7F912BA51793000EEEBE /* ReviewsFeed.h */,
|
02A6DA2F2BA591C000B943E2 /* Bundle */,
|
||||||
02DC7FB02BA51B4F000EEEBE /* Sources */,
|
02A6DA302BA5929F00B943E2 /* Test */,
|
||||||
);
|
);
|
||||||
path = Feed;
|
path = Feed;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -166,7 +182,7 @@
|
|||||||
02DC7FB12BA52084000EEEBE /* Libraries */,
|
02DC7FB12BA52084000EEEBE /* Libraries */,
|
||||||
02DC7FAB2BA51848000EEEBE /* Frameworks */,
|
02DC7FAB2BA51848000EEEBE /* Frameworks */,
|
||||||
345AD11A24C6EDD9004E2EE1 /* App */,
|
345AD11A24C6EDD9004E2EE1 /* App */,
|
||||||
02900C4A2BA53162008D2E8D /* Test Plans */,
|
02900C4C2BA5347A008D2E8D /* Test Plans */,
|
||||||
345AD11924C6EDD9004E2EE1 /* Products */,
|
345AD11924C6EDD9004E2EE1 /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user