This PR contains the work done to implement the `iTunesService` service that fetches the reviews from the **Apple App Store**. Reviewed-on: #5 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
71 lines
1.8 KiB
Swift
71 lines
1.8 KiB
Swift
//
|
|
// GetReviewsAPIEndpoint.swift
|
|
// ReviewsiTunesKit
|
|
//
|
|
// Created by Javier Cicchelli on 17/03/2024.
|
|
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import ReviewsFoundationKit
|
|
import ReviewsFeedKit
|
|
|
|
struct GetReviewsAPIEndpoint: GetReviewsEndpoint {
|
|
|
|
// MARK: Constants
|
|
let host: URL
|
|
let decoder: JSONDecoder
|
|
let session: URLSession
|
|
|
|
// MARK: Functions
|
|
@discardableResult func callAsFunction(
|
|
_ input: ReviewsFeedKit.GetReviewsInput
|
|
) async throws -> ReviewsFeedKit.GetReviewsOutput {
|
|
let path = try makePath(with: input)
|
|
let url = {
|
|
if #available(iOS 16.0, *) {
|
|
host.appending(path: path)
|
|
} else {
|
|
host.appendingPathComponent(path)
|
|
}
|
|
}()
|
|
|
|
let (data, response) = try await session.data(from: url)
|
|
|
|
guard let urlResponse = response as? HTTPURLResponse else {
|
|
throw EndpointError.responseNotFound
|
|
}
|
|
|
|
guard urlResponse.statusCode == 200 else {
|
|
throw EndpointError.requestFailed(statusCode: urlResponse.statusCode)
|
|
}
|
|
|
|
let feed = try decoder.decode(Feed.self, from: data)
|
|
|
|
return .init(reviews: feed.entries)
|
|
}
|
|
|
|
func makePath(with input: GetReviewsInput) throws -> String {
|
|
guard
|
|
!input.appID.isEmpty,
|
|
!input.countryCode.isEmpty
|
|
else{
|
|
throw EndpointError.inputParametersEmpty
|
|
}
|
|
|
|
return .init(
|
|
format: .Format.recentReviewsPath,
|
|
input.countryCode,
|
|
input.appID
|
|
)
|
|
}
|
|
|
|
}
|
|
|
|
// MARK: - String+Formats
|
|
private extension String {
|
|
enum Format {
|
|
static let recentReviewsPath = "/%@/rss/customerreviews/id=%@/sortby=mostrecent/json"
|
|
}
|
|
}
|