[Library] iTunes library (#5)

This PR contains the work done to implement the `iTunesService` service that fetches the reviews from the **Apple App Store**.

Reviewed-on: rock-n-code/app-reviews#5
Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #5.
This commit is contained in:
2024-03-17 22:48:27 +00:00
committed by javier
parent 4359f53a19
commit 7c016b50d6
18 changed files with 850 additions and 3 deletions
+51
View File
@@ -0,0 +1,51 @@
//
// Feed.swift
// ReviewsiTunesKit
//
// Created by Javier Cicchelli on 17/03/2024.
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
//
import ReviewsFeedKit
struct Feed {
// MARK: Constants
let entries: [Review]
}
// MARK: - Decodable
extension Feed: Decodable {
// MARK: Enumerations
enum FeedKeys: String, CodingKey {
case feed
}
enum EntryKeys: String, CodingKey {
case entry
}
// MARK: Initialisers
init(from decoder: any Decoder) throws {
let feed = try decoder.container(keyedBy: FeedKeys.self)
let feedEntry = try feed.nestedContainer(keyedBy: EntryKeys.self, forKey: .feed)
self.entries = try feedEntry.decode([Review].self, forKey: .entry)
}
}
// MARK: - Encodable
extension Feed: Encodable {
// MARK: Functions
func encode(to encoder: any Encoder) throws {
var feed = encoder.container(keyedBy: FeedKeys.self)
var feedEntry = feed.nestedContainer(keyedBy: EntryKeys.self, forKey: .feed)
try feedEntry.encode(entries, forKey: .entry)
}
}
@@ -0,0 +1,84 @@
//
// Review+Codable.swift
// ReviewsiTunesKit
//
// Created by Javier Cicchelli on 17/03/2024.
// Copyright © 2024 Röck+Cöde VoF. All rights reserved.
//
import Foundation
import ReviewsFeedKit
// MARK: - Decodable
extension Review: Decodable {
// MARK: Enumerations
enum ReviewKeys: String, CodingKey {
case author
case content
case id
case rating = "im:rating"
case title
case updated
case version = "im:version"
}
enum NameKeys: String, CodingKey {
case name
}
enum LabelKeys: String, CodingKey {
case label
}
// MARK: Initialisers
public init(from decoder: any Decoder) throws {
let review = try decoder.container(keyedBy: ReviewKeys.self)
let authorName = try review.nestedContainer(keyedBy: NameKeys.self, forKey: .author)
let authorLabel = try authorName.nestedContainer(keyedBy: LabelKeys.self, forKey: .name)
let contentLabel = try review.nestedContainer(keyedBy: LabelKeys.self, forKey: .content)
let idLabel = try review.nestedContainer(keyedBy: LabelKeys.self, forKey: .id)
let ratingLabel = try review.nestedContainer(keyedBy: LabelKeys.self, forKey: .rating)
let titleLabel = try review.nestedContainer(keyedBy: LabelKeys.self, forKey: .title)
let versionLabel = try review.nestedContainer(keyedBy: LabelKeys.self, forKey: .version)
let updatedLabel = try review.nestedContainer(keyedBy: LabelKeys.self, forKey: .updated)
self.init(
id: Int(try idLabel.decode(String.self, forKey: .label)) ?? 0,
author: try authorLabel.decode(String.self, forKey: .label),
title: try titleLabel.decode(String.self, forKey: .label),
content: try contentLabel.decode(String.self, forKey: .label),
rating: Int(try ratingLabel.decode(String.self, forKey: .label)) ?? 0,
version: try versionLabel.decode(String.self, forKey: .label),
updated: try updatedLabel.decode(Date.self, forKey: .label)
)
}
}
// MARK: - Encodable
extension Review: Encodable {
// MARK: Functions
public func encode(to encoder: any Encoder) throws {
var review = encoder.container(keyedBy: ReviewKeys.self)
var authorName = review.nestedContainer(keyedBy: NameKeys.self, forKey: .author)
var authorLabel = authorName.nestedContainer(keyedBy: LabelKeys.self, forKey: .name)
var contentLabel = review.nestedContainer(keyedBy: LabelKeys.self, forKey: .content)
var idLabel = review.nestedContainer(keyedBy: LabelKeys.self, forKey: .id)
var ratingLabel = review.nestedContainer(keyedBy: LabelKeys.self, forKey: .rating)
var titleLabel = review.nestedContainer(keyedBy: LabelKeys.self, forKey: .title)
var versionLabel = review.nestedContainer(keyedBy: LabelKeys.self, forKey: .version)
var updatedLabel = review.nestedContainer(keyedBy: LabelKeys.self, forKey: .updated)
try authorLabel.encode(author, forKey: .label)
try contentLabel.encode(content, forKey: .label)
try idLabel.encode(String(id), forKey: .label)
try ratingLabel.encode(String(rating), forKey: .label)
try titleLabel.encode(title, forKey: .label)
try versionLabel.encode(version, forKey: .label)
try updatedLabel.encode(updated, forKey: .label)
}
}