[Setup] Documentation (#10)
This PR contains the work done to address the issue #7, related to documenting the source code that would be used for other developers. To provide further details about the work done: - [x] restructured the hierarchy of some models that are related to the `Amiibo` model; - [x] written documentation for the `AmiiboService` service; - [x] written documentation for the `AmiiboFilter` and `KeyNameFilter` filters; - [x] written documentation for the `Amiibo`, `KeyName`, `LastUpdated` and children model; - [x] written documentation for the `AmiiboClientError` error; - [x] written documentation for the README file. Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Reviewed-on: #10
This commit is contained in:
parent
a0dcdf7673
commit
c4a25afad4
71
README.md
71
README.md
@ -1,3 +1,70 @@
|
||||
# AmiiboService
|
||||
# AmiiboService: Amiibo API service written in Swift
|
||||
|
||||
A description of this package.
|
||||
This package contains a ready-to-use service that can retrieve data as decoded models/entities from any of the [Amiibo API](https://www.amiiboapi.com) available endpoints.
|
||||
|
||||
## Installation
|
||||
|
||||
It is possible to add this library in your projects either by explicitly add it as a dependency either in a `Package.swift` file or in your Xcode project.
|
||||
|
||||
This package has minimum platform requirements that are important to take into account:
|
||||
* *iOS 13.0 or higher*;
|
||||
* *macOS 10.15 or higher*;
|
||||
* *tvOS 13.0 or higher*;
|
||||
* *watchOS 8.0 or higher*;
|
||||
|
||||
### Package file
|
||||
|
||||
In the intended `Package.swift` file, it is required to add the following dependency:
|
||||
|
||||
```swift
|
||||
dependencies: [
|
||||
// ...
|
||||
.package(url: "https://github.com/rock-n-code/amiibo-service.git", from: "1.0.0")
|
||||
// ...
|
||||
],
|
||||
```
|
||||
|
||||
Then it is required to add the package to your target, like this:
|
||||
|
||||
```swift
|
||||
targets: [
|
||||
.target(
|
||||
...
|
||||
dependencies: [
|
||||
.product(name: "AmiiboService", package: "amiibo-service")
|
||||
],
|
||||
...
|
||||
),
|
||||
]
|
||||
```
|
||||
|
||||
### Xcode
|
||||
|
||||
In an opened Xcode project, it is required to do these steps:
|
||||
1. click on your Xcode project file to display *Project* and *Targets*;
|
||||
2. select the project under the *Project* section to show the *Info*, *Build Settings* and *Package Dependencies* in the center menu of the screen;
|
||||
3. select the *Package Dependencies* to show the defined dependencies of the project;
|
||||
4. press on the *+* (plus) button to add dependencies to the project;
|
||||
5. enter the URL`https://github.com/rock-n-code/amiibo-service` into the *Search or Enter Package URL* located in the upper right corner;
|
||||
6. select the given option;
|
||||
7. define the dependency rule (the *Up to Next Major Version* option and the *1.0.0* text are recommended);
|
||||
8. select the target to which the dependency will be applied (if required);
|
||||
9. wait for the package to be resolved and included in the project;
|
||||
10. done!
|
||||
|
||||
|
||||
### Other considerations
|
||||
|
||||
This library is fully supported on Apple platforms only for the time being: *iOS*, *macOS*, *tvOS*, and *watchOS*. Support for other platforms such as *Linux* or *Windows* might be added in the future, depending on the type of changes those platforms require but this needs to be researched first.
|
||||
|
||||
⚠️ Please notice that this library only supports the [Swift Package Manager](https://www.swift.org/package-manager/), and that support for other dependency managers such as *Cocoapods* and *Carthage* is not planned.
|
||||
|
||||
## Usage
|
||||
|
||||
This package provides an actor called `AmiiboService` which, after is initialised, is responsible for making requests based on a given filter criteria to the remote API, handling the responses, and decoding the retrieved data into models/entities structs, or throws errors if necessary.
|
||||
|
||||
It is needless to say, all the necessary filters, models/entities, and enumerations are also provided in this package.
|
||||
|
||||
## Further documentation
|
||||
|
||||
For further information about the API, please refer to the [Amiibo API documentation](https://www.amiiboapi.com/docs/) available online.
|
||||
|
@ -1,4 +1,7 @@
|
||||
/// This error definitions represents any error happening while the client makes a request to the remote API and handles the respective response, excluding the decoding of the retrieved data into a particular model.
|
||||
public enum AmiiboClientError: Error {
|
||||
/// The status code of the response is not the expected one, which is `.ok` (`200`).
|
||||
case responseCode(Int)
|
||||
/// The status code of the response was not received at all.
|
||||
case responseCodeNotFound
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
/// This filter provides all the possible parameters (and combinations) available at the remote API applies when filtering amiibos.
|
||||
public struct AmiiboFilter {
|
||||
|
||||
// MARK: Properties
|
||||
@ -14,6 +15,17 @@ public struct AmiiboFilter {
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
/// Initialises this filter.
|
||||
/// - Parameters:
|
||||
/// - id: An amiibo `id` value to match against.
|
||||
/// - head: An amiibo `head` value to match against.
|
||||
/// - tail: An amiibo `tail` value to match against.
|
||||
/// - name: An amiibo `name` value to match against.
|
||||
/// - type: An amiibo `type` key or name value to match against.
|
||||
/// - gameSeries: An amiibo `gameSeries` key or name value to match against.
|
||||
/// - amiiboSeries: An amiibo `amiiboSeries` key or name value to match against.
|
||||
/// - character: An amiibo `character` key or name value to match against.
|
||||
/// - showExtras: A ``ShowExtras`` enumeration that indicates whether amiibo extra information need to be retrieved or not.
|
||||
public init(
|
||||
id: String? = nil,
|
||||
head: String? = nil,
|
||||
@ -95,10 +107,16 @@ extension AmiiboFilter: Filter {
|
||||
|
||||
// MARK: - Enumerations
|
||||
|
||||
public enum ShowExtras {
|
||||
case none
|
||||
case games
|
||||
case usage
|
||||
extension AmiiboFilter {
|
||||
/// This enumeration indicates if extra information for amiibos need to be retrieved.
|
||||
public enum ShowExtras {
|
||||
/// No extra information needs to be retrieved.
|
||||
case none
|
||||
/// Amiibo games information needs to be retrieved.
|
||||
case games
|
||||
/// Amiibo games and its usage information needs to be retrieved.
|
||||
case usage
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - String+Key
|
||||
|
@ -1,3 +1,4 @@
|
||||
/// This filter provides all the possible parameters (and combinations) available at the remote API applies when filtering amiibos series (``AmiiboSeriesFilter``), amiibo types (``AmiiboTypeFilter``), characters (``CharacterFilter``), or game series (``GameSeriesFilter``).
|
||||
public struct KeyNameFilter {
|
||||
|
||||
// MARK: Properties
|
||||
@ -7,6 +8,10 @@ public struct KeyNameFilter {
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
/// Initialises this filter.
|
||||
/// - Parameters:
|
||||
/// - key: A `key` value to match against.
|
||||
/// - name: A `name` value to match against.
|
||||
public init(
|
||||
key: String? = nil,
|
||||
name: String? = nil
|
||||
@ -17,6 +22,20 @@ public struct KeyNameFilter {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Type aliases
|
||||
|
||||
/// This filter provides all the possible parameters (and combinations) available at the remote API applies when filtering amiibos series.
|
||||
public typealias AmiiboSeriesFilter = KeyNameFilter
|
||||
|
||||
/// This filter provides all the possible parameters (and combinations) available at the remote API applies when filtering amiibo types.
|
||||
public typealias AmiiboTypeFilter = KeyNameFilter
|
||||
|
||||
/// This filter provides all the possible parameters (and combinations) available at the remote API applies when filtering characters.
|
||||
public typealias CharacterFilter = KeyNameFilter
|
||||
|
||||
/// This filter provides all the possible parameters (and combinations) available at the remote API applies when filtering game series.
|
||||
public typealias GameSeriesFilter = KeyNameFilter
|
||||
|
||||
// MARK: - Filter
|
||||
|
||||
extension KeyNameFilter: Filter {
|
||||
@ -39,13 +58,6 @@ extension KeyNameFilter: Filter {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Type aliases
|
||||
|
||||
public typealias AmiiboSeriesFilter = KeyNameFilter
|
||||
public typealias AmiiboTypeFilter = KeyNameFilter
|
||||
public typealias CharacterFilter = KeyNameFilter
|
||||
public typealias GameSeriesFilter = KeyNameFilter
|
||||
|
||||
// MARK: - String+Key
|
||||
|
||||
private extension String {
|
||||
|
@ -1,22 +1,54 @@
|
||||
/// This model struct represents an amiibo that is retrieved from the respective [remote API endpoint](https://www.amiiboapi.com/docs/#amiibo).
|
||||
public struct Amiibo {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The type the amiibo belongs to.
|
||||
public let type: String
|
||||
|
||||
/// The first 8 values of the hexadecimal that identifies the amiibo.
|
||||
public let head: String
|
||||
|
||||
/// The last 8 values of the hexadecimal that identifies the amiibo.
|
||||
public let tail: String
|
||||
|
||||
/// The name of the amiibo.
|
||||
public let name: String
|
||||
|
||||
/// The character of the amiibo.
|
||||
public let character: String
|
||||
|
||||
/// The series the amiibo belongs to.
|
||||
public let series: String
|
||||
|
||||
/// The game series of the amiibo.
|
||||
public let gameSeries: String
|
||||
|
||||
/// The URL to an image of the amiibo.
|
||||
public let image: String
|
||||
|
||||
/// The release dates of the amiibo (if released) in Australia, Europe, Japan and North America.
|
||||
public let release: Release
|
||||
|
||||
/// The games related to the amiibo, if requested.
|
||||
public let games: Games?
|
||||
}
|
||||
|
||||
// MARK: - Structs
|
||||
|
||||
extension Amiibo {
|
||||
/// This model represents the list of games related to a particular amiibo, grouped by system.
|
||||
public struct Games: Decodable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A list of [Nintendo 3DS system](https://en.wikipedia.org/wiki/Nintendo_3DS) games the amiibo can be used with.
|
||||
public let n3ds: [Game]
|
||||
|
||||
/// A list of [Nintendo WiiU system](https://en.wikipedia.org/wiki/Wii_U) games the amiibo can be used with.
|
||||
public let wiiu: [Game]
|
||||
|
||||
/// /// A list of [Nintendo Switch system](https://en.wikipedia.org/wiki/Nintendo_Switch) games the amiibo can be used with.
|
||||
public let `switch`: [Game]
|
||||
}
|
||||
}
|
||||
@ -44,6 +76,9 @@ extension Amiibo: Decodable {
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
/// Initialises this model by decoding from the given decoder.
|
||||
/// - Parameter decoder: The decoder to read data from.
|
||||
/// - Throws: A `DecodingError` error in case the decode failed at decoding data into an expected model type.
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let games3ds = try container.decodeIfPresent([Game].self, forKey: .games3DS)
|
||||
|
27
Sources/Models/AmiiboGame.swift
Normal file
27
Sources/Models/AmiiboGame.swift
Normal file
@ -0,0 +1,27 @@
|
||||
extension Amiibo {
|
||||
/// This model structs represents a game that is related to an amiibo, when requested to the respective [remote API endpoint](https://www.amiiboapi.com/docs/#showGames).
|
||||
public struct Game {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The list of identifiers associated to the game.
|
||||
public let ids: [String]
|
||||
|
||||
/// The name of the game.
|
||||
public let name: String
|
||||
|
||||
/// The list of usages that explains how the amiibo is being used in the game.
|
||||
public let usage: [Usage]?
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Decodable
|
||||
|
||||
extension Amiibo.Game: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case ids = "gameID"
|
||||
case name = "gameName"
|
||||
case usage = "amiiboUsage"
|
||||
}
|
||||
}
|
23
Sources/Models/AmiiboGameUsage.swift
Normal file
23
Sources/Models/AmiiboGameUsage.swift
Normal file
@ -0,0 +1,23 @@
|
||||
extension Amiibo.Game {
|
||||
/// This model struct represents how an amiibo is used with a particular game, when requested to the respective [remote API endpoint](https://www.amiiboapi.com/docs/#showUsage).
|
||||
public struct Usage {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The explanation on how an amiibo is being used with a particular game.
|
||||
public let explanation: String
|
||||
|
||||
/// A flag that indicates whether an amiibo is only read-only or the game can also write information to the amiibo.
|
||||
public let isWritable: Bool
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Decodable
|
||||
|
||||
extension Amiibo.Game.Usage: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case explanation = "Usage"
|
||||
case isWritable = "write"
|
||||
}
|
||||
}
|
33
Sources/Models/AmiiboRelease.swift
Normal file
33
Sources/Models/AmiiboRelease.swift
Normal file
@ -0,0 +1,33 @@
|
||||
import Foundation
|
||||
|
||||
extension Amiibo {
|
||||
/// This model struct represents a collection of official release dates (if released) of an amiibo in different markets around the world.
|
||||
public struct Release {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The official release date (if released) of an amiibo in Australia.
|
||||
public let australia: Date?
|
||||
|
||||
/// The official release date (if released) of an amiibo in Europe.
|
||||
public let europe: Date?
|
||||
|
||||
/// The official release date (if released) of an amiibo in Japan.
|
||||
public let japan: Date?
|
||||
|
||||
/// The official release date (if released) of an amiibo in North America.
|
||||
public let america: Date?
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Decodable
|
||||
|
||||
extension Amiibo.Release: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case australia = "au"
|
||||
case europe = "eu"
|
||||
case japan = "jp"
|
||||
case america = "na"
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
public struct Game {
|
||||
public let ids: [String]
|
||||
public let name: String
|
||||
public let usage: [Usage]?
|
||||
}
|
||||
|
||||
// MARK: - Decodable
|
||||
|
||||
extension Game: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case ids = "gameID"
|
||||
case name = "gameName"
|
||||
case usage = "amiiboUsage"
|
||||
}
|
||||
}
|
@ -1,15 +1,30 @@
|
||||
/// This model is a concrete genetic definition that represents the following models: ``AmiiboSeries``, ``AmiiboType``, ``Character`` and ``GameSeries``.
|
||||
public struct KeyName {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The key of the model.
|
||||
public let key: String
|
||||
public let name: String?
|
||||
|
||||
/// The name of the model.
|
||||
public let name: String
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Type aliases
|
||||
|
||||
/// This model represents the series an amiibo belongs to.
|
||||
public typealias AmiiboSeries = KeyName
|
||||
|
||||
/// This model represents the type an amiibo belongs to.
|
||||
public typealias AmiiboType = KeyName
|
||||
|
||||
/// This model represents the character an amiibo is associated to.
|
||||
public typealias Character = KeyName
|
||||
|
||||
/// This model represents the games series an amiibo is associated to.
|
||||
public typealias GameSeries = KeyName
|
||||
|
||||
// MARK: - Decodable
|
||||
|
||||
extension KeyName: Decodable {}
|
||||
|
||||
// MARK: - Type aliases
|
||||
|
||||
public typealias AmiiboType = KeyName
|
||||
public typealias AmiiboSeries = KeyName
|
||||
public typealias GameSeries = KeyName
|
||||
public typealias Character = KeyName
|
||||
|
@ -1,7 +1,13 @@
|
||||
import Foundation
|
||||
|
||||
/// This model represents the latest date when the remote API has been updated.
|
||||
public struct LastUpdated {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The date of the latest update of the remote API.
|
||||
public let timestamp: Date
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Decodable
|
||||
|
@ -1,19 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
public struct Release {
|
||||
public let australia: Date?
|
||||
public let europe: Date?
|
||||
public let japan: Date?
|
||||
public let america: Date?
|
||||
}
|
||||
|
||||
// MARK: - Decodable
|
||||
|
||||
extension Release: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case australia = "au"
|
||||
case europe = "eu"
|
||||
case japan = "jp"
|
||||
case america = "na"
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
public struct Usage {
|
||||
public let explanation: String
|
||||
public let isWritable: Bool
|
||||
}
|
||||
|
||||
// MARK: - Decodable
|
||||
|
||||
extension Usage: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case explanation = "Usage"
|
||||
case isWritable = "write"
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
import Foundation
|
||||
|
||||
public struct AmiiboService {
|
||||
/// This service provides the interface to make remote API calls to the [Amiibo API](https://www.amiiboapi.com) and, subsequently, handle its responses.
|
||||
///
|
||||
/// Given that this remote service is a read-only API, this service will exclusively return decoded models or entities in cases the requests are successful, or it will throw errors otherwise.
|
||||
public actor AmiiboService {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
@ -8,7 +11,9 @@ public struct AmiiboService {
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
init(configuration: URLSessionConfiguration) {
|
||||
/// Initialises this service.
|
||||
/// - Parameter configuration: The `URLSessionConfiguration` configuration to use to set this service.
|
||||
public init(configuration: URLSessionConfiguration) {
|
||||
self.client = .init(configuration: configuration)
|
||||
}
|
||||
|
||||
@ -20,6 +25,10 @@ extension AmiiboService: Service {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
/// Retrieves a list of amiibos from a remote location that matches a given filter criteria.
|
||||
/// - Parameter filter: A ``AmiiboFilter`` instance that contains the filtering criteria.
|
||||
/// - Returns: A list of decoded ``Amiibo`` instances that matches the given filter criteria.
|
||||
/// - Throws: A ``AmiiboClientError`` is thrown in case a request failed, or a `DecodingError` is thrown in case the decoding of some object failed.
|
||||
public func amiibos(
|
||||
filter: AmiiboFilter = .init()
|
||||
) async throws -> [Amiibo] {
|
||||
@ -31,6 +40,10 @@ extension AmiiboService: Service {
|
||||
).items
|
||||
}
|
||||
|
||||
/// Retrieves a list of amiibo series from a remote location that matches a given filter criteria.
|
||||
/// - Parameter filter: A ``AmiiboSeriesFilter`` instance that contains the filtering criteria.
|
||||
/// - Returns: A list of decoded ``AmiiboSeries`` instances that matches the given filter criteria.
|
||||
/// - Throws: A ``AmiiboClientError`` is thrown in case a request failed, or a `DecodingError` is thrown in case the decoding of some object failed.
|
||||
public func amiiboSeries(
|
||||
filter: AmiiboSeriesFilter = .init()
|
||||
) async throws -> [AmiiboSeries] {
|
||||
@ -42,6 +55,10 @@ extension AmiiboService: Service {
|
||||
).items
|
||||
}
|
||||
|
||||
/// Retrieves a list of amiibo types from a remote location that matches a given filter criteria.
|
||||
/// - Parameter filter: A ``AmiiboTypeFilter`` instance that contains the filtering criteria.
|
||||
/// - Returns: A list of decoded ``AmiiboType`` instances that matches the given filter criteria.
|
||||
/// - Throws: A ``AmiiboClientError`` is thrown in case a request failed, or a `DecodingError` is thrown in case the decoding of some object failed.
|
||||
public func amiiboTypes(
|
||||
filter: AmiiboTypeFilter = .init()
|
||||
) async throws -> [AmiiboType] {
|
||||
@ -53,6 +70,10 @@ extension AmiiboService: Service {
|
||||
).items
|
||||
}
|
||||
|
||||
/// Retrieves a list of characters from a remote location that matches a given filter criteria.
|
||||
/// - Parameter filter: A ``CharacterFilter`` instance that contains the filtering criteria.
|
||||
/// - Returns: A list of decoded ``Character`` instances that matches the given filter criteria.
|
||||
/// - Throws: A ``AmiiboClientError`` is thrown in case a request failed, or a `DecodingError` is thrown in case the decoding of some object failed.
|
||||
public func characters(
|
||||
filter: CharacterFilter = .init()
|
||||
) async throws -> [Character] {
|
||||
@ -64,6 +85,10 @@ extension AmiiboService: Service {
|
||||
).items
|
||||
}
|
||||
|
||||
/// Retrieves a list of game series from a remote location that matches a given filter criteria.
|
||||
/// - Parameter filter: A ``GameSeriesFilter`` instance that contains the filtering criteria.
|
||||
/// - Returns: A list of decoded ``GameSeries`` instances that matches the given filter criteria.
|
||||
/// - Throws: A ``AmiiboClientError`` is thrown in case a request failed, or a `DecodingError` is thrown in case the decoding of some object failed.
|
||||
public func gameSeries(
|
||||
filter: GameSeriesFilter = .init()
|
||||
) async throws -> [GameSeries] {
|
||||
@ -75,6 +100,9 @@ extension AmiiboService: Service {
|
||||
).items
|
||||
}
|
||||
|
||||
/// Retrieves the date in which the remote API was last updated.
|
||||
/// - Returns: A `Date` instance that represents the date in which the remote API was last updated.
|
||||
/// - Throws: A ``AmiiboClientError`` is thrown in case a request failed, or a `DecodingError` is thrown in case the decoding of some object failed.
|
||||
public func lastUpdated() async throws -> Date {
|
||||
client.setDateDecodingStrategy(.formatted(.dateAndTime))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user