[Framework] Feed list view in the Feed framework (#9)

This PR contains the work done to provide the existing `FeedViewController` view controller with real life data by integrating the `iTunesService` service into its view model. In addition, the list item cell has been design has been updated, and re-implemented using the `SwiftUI` framework.

Reviewed-on: rock-n-code/app-reviews#9
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 #9.
This commit is contained in:
2024-03-19 08:31:13 +00:00
committed by javier
parent 26c2c0c581
commit 09df006ab9
16 changed files with 664 additions and 166 deletions
@@ -0,0 +1,31 @@
//
// Review.swift
// ReviewsFeed
//
// Created by Dmitrii Ivanov on 21/07/2020.
// Copyright © 2020 ING. All rights reserved.
//
import Foundation
struct Review {
// MARK: Constants
let author: String
let comment: String
let id: Int
let rating: Rating
let title: String
}
// MARK: - Structs
extension Review {
struct Rating {
// MARK: Constants
let stars: Int
let appVersion: String
}
}
@@ -0,0 +1,69 @@
//
// FeedViewModel.swift
// ReviewsFeed
//
// Created by Javier Cicchelli on 18/03/2024.
// Copyright © 2024 Röck+Cöde. All rights reserved.
//
import Foundation
import ReviewsiTunesKit
extension FeedViewController {
final class ViewModel: ObservableObject {
// MARK: Type aliases
typealias Configuration = FeedViewController.Configuration
// MARK: Constants
private let configuration: Configuration
// MARK: Properties
@Published var loading: Bool = false
var items: [Review] = []
// MARK: Initialisers
init(configuration: Configuration = .init()) {
self.configuration = configuration
}
// MARK: Computed
lazy private var iTunesService: iTunesService = {
.init(configuration: .init(session: configuration.session))
}()
// MARK: Functions
func fetch() {
Task {
loading = true
do {
let output = try await iTunesService.getReviews(.init(
appID: configuration.appID,
countryCode: configuration.countryCode
))
items = output.reviews
.map { review -> Review in
.init(
author: review.author,
comment: review.content,
id: review.id,
rating: .init(
stars: review.rating,
appVersion: review.version
),
title: review.title
)
}
} catch {
// TODO: handle this error gracefully.
}
loading = false
}
}
}
}