[Enhancement] Linux platform support #17
@ -10,16 +10,18 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
|
|
||||||
import Communications
|
import Communications
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
#if canImport(FoundationNetworking)
|
||||||
|
import FoundationNetworking
|
||||||
|
#endif
|
||||||
|
|
||||||
struct AmiiboClient {
|
struct AmiiboClient {
|
||||||
|
|
||||||
// MARK: Properties
|
// MARK: Properties
|
||||||
|
|
||||||
private let session: URLSession
|
private let session: URLSession
|
||||||
|
|
||||||
private let decoder = JSONDecoder()
|
private let decoder = JSONDecoder()
|
||||||
private let makeURLRequest = MakeURLRequestUseCase()
|
private let makeURLRequest = MakeURLRequestUseCase()
|
||||||
|
|
||||||
@ -48,7 +50,7 @@ extension AmiiboClient: Client {
|
|||||||
as model: Model.Type
|
as model: Model.Type
|
||||||
) async throws -> Model where Model : Decodable {
|
) async throws -> Model where Model : Decodable {
|
||||||
let urlRequest = try makeURLRequest(endpoint: endpoint)
|
let urlRequest = try makeURLRequest(endpoint: endpoint)
|
||||||
let (data, response) = try await session.data(for: urlRequest)
|
let (data, response) = try await data(from: session, for: urlRequest)
|
||||||
|
|
||||||
try check(response)
|
try check(response)
|
||||||
|
|
||||||
@ -63,6 +65,27 @@ private extension AmiiboClient {
|
|||||||
|
|
||||||
// MARK: Functions
|
// MARK: Functions
|
||||||
|
|
||||||
|
func data(
|
||||||
|
from session: URLSession,
|
||||||
|
for urlRequest: URLRequest
|
||||||
|
) async throws -> (Data, URLResponse) {
|
||||||
|
#if canImport(FoundationNetworking)
|
||||||
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
|
session.dataTask(with: urlRequest) { data, response, error in
|
||||||
|
if let error {
|
||||||
|
continuation.resume(with: .failure(error))
|
||||||
|
} else if let data, let response {
|
||||||
|
continuation.resume(with: .success((data, response)))
|
||||||
|
} else {
|
||||||
|
continuation.resume(with: .failure(AmiiboClientError.dataOrResponseNotFound))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
try await session.data(for: urlRequest)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
func check(_ response: URLResponse) throws {
|
func check(_ response: URLResponse) throws {
|
||||||
guard
|
guard
|
||||||
let urlResponse = response as? HTTPURLResponse,
|
let urlResponse = response as? HTTPURLResponse,
|
||||||
@ -77,4 +100,3 @@ private extension AmiiboClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
/// 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.
|
/// 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 {
|
public enum AmiiboClientError: Error {
|
||||||
|
/// The data and/or response expected from an API call are not found.
|
||||||
|
case dataOrResponseNotFound
|
||||||
/// The status code of the response is not the expected one, which is `.ok` (`200`).
|
/// The status code of the response is not the expected one, which is `.ok` (`200`).
|
||||||
case responseCode(Int)
|
case responseCode(Int)
|
||||||
/// The status code of the response was not received at all.
|
/// The status code of the response was not received at all.
|
||||||
|
@ -10,9 +10,12 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
#if canImport(FoundationNetworking)
|
||||||
|
import FoundationNetworking
|
||||||
|
#endif
|
||||||
|
|
||||||
/// This service provides the interface to make remote API calls to the [Amiibo API](https://www.amiiboapi.com) and, subsequently, handle its responses.
|
/// 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.
|
/// 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.
|
||||||
@ -126,4 +129,3 @@ extension AmiiboService: Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -10,11 +10,14 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
|
|
||||||
import Communications
|
import Communications
|
||||||
import Foundation
|
import Foundation
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
|
#if canImport(FoundationNetworking)
|
||||||
|
import FoundationNetworking
|
||||||
|
#endif
|
||||||
|
|
||||||
@testable import AmiiboService
|
@testable import AmiiboService
|
||||||
|
|
||||||
final class AmiiboClientTests: XCTestCase {
|
final class AmiiboClientTests: XCTestCase {
|
||||||
@ -156,4 +159,3 @@ final class AmiiboClientTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -10,10 +10,13 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
|
|
||||||
import Communications
|
import Communications
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
#if canImport(FoundationNetworking)
|
||||||
|
import FoundationNetworking
|
||||||
|
#endif
|
||||||
|
|
||||||
extension MockURLRequest {
|
extension MockURLRequest {
|
||||||
|
|
||||||
// MARK: Initialisers
|
// MARK: Initialisers
|
||||||
@ -23,4 +26,3 @@ extension MockURLRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -10,11 +10,14 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
|
|
||||||
import Communications
|
import Communications
|
||||||
import Foundation
|
import Foundation
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
|
#if canImport(FoundationNetworking)
|
||||||
|
import FoundationNetworking
|
||||||
|
#endif
|
||||||
|
|
||||||
@testable import AmiiboService
|
@testable import AmiiboService
|
||||||
|
|
||||||
final class AmiiboServiceTests: XCTestCase {
|
final class AmiiboServiceTests: XCTestCase {
|
||||||
@ -522,4 +525,3 @@ final class AmiiboServiceTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user