From d45a3d95f98163abbc270973a04c89acfc5da7ef Mon Sep 17 00:00:00 2001 From: Viktoriia Kostyleva Date: Mon, 3 Oct 2022 13:51:51 +0300 Subject: [PATCH 1/3] #5: Add GET countries request --- .../NodesProvider/Models/Country.swift | 27 +++++++++++++++++++ .../NodesProvider/NodesAPITarget.swift | 7 +++++ .../NodesProvider/NodesProvider.swift | 7 +++++ .../NodesProvider/NodesProviderType.swift | 2 ++ .../project.pbxproj | 4 +++ .../Nodes/NodesRouteCollection.swift | 7 ++++- .../Services/NodesService/NodesService.swift | 13 +++++++++ .../NodesService/NodesServiceType.swift | 2 ++ 8 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/Models/Country.swift diff --git a/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/Models/Country.swift b/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/Models/Country.swift new file mode 100644 index 0000000..4d034ee --- /dev/null +++ b/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/Models/Country.swift @@ -0,0 +1,27 @@ +// +// Country.swift +// SOLARAPI +// +// Created by Viktoriia Kostyleva on 03.10.2022. +// + +import Foundation + +public struct Country: Codable { + public let code: String + public let nodesCount: Int + + public init(code: String, nodesCount: Int) { + self.code = code + self.nodesCount = nodesCount + } +} + +// MARK: - Codable implementation + +public extension Country { + enum CodingKeys: String, CodingKey { + case code + case nodesCount = "nodes_count" + } +} diff --git a/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesAPITarget.swift b/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesAPITarget.swift index f7ce7d5..372ba60 100644 --- a/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesAPITarget.swift +++ b/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesAPITarget.swift @@ -11,6 +11,7 @@ import Alamofire enum NodesAPITarget { case getNodes(GetNodesRequest) case postNodesByAddress(PostNodesByAddressRequest) + case getCountries } extension NodesAPITarget: APITarget { @@ -20,6 +21,8 @@ extension NodesAPITarget: APITarget { return .get case .postNodesByAddress: return .post + case .getCountries: + return .get } } @@ -29,6 +32,8 @@ extension NodesAPITarget: APITarget { return "dvpn/getNodes" case .postNodesByAddress: return "dvpn/postNodesByAddress" + case .getCountries: + return "dvpn/getCountries" } } @@ -38,6 +43,8 @@ extension NodesAPITarget: APITarget { return .requestParameters(parameters: request.dictionary ?? [:], encoding: URLEncoding.default) case let .postNodesByAddress(request): return .requestJSONEncodable(request) + case .getCountries: + return .requestPlain } } } diff --git a/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesProvider.swift b/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesProvider.swift index 0d66064..aeac5d3 100644 --- a/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesProvider.swift +++ b/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesProvider.swift @@ -44,6 +44,13 @@ extension NodesProvider: NodesProviderType { .validate() .responseDecodable(completionHandler: getResponseHandler(completion: completion)) } + + public func getCountries(completion: @escaping (Result<[Country], NetworkError>) -> Void) { + AF + .request(request(for: .getCountries)) + .validate() + .responseDecodable(completionHandler: getResponseHandler(completion: completion)) + } } private extension NodesProvider { diff --git a/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesProviderType.swift b/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesProviderType.swift index 8ba8630..92c1037 100644 --- a/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesProviderType.swift +++ b/SolardVPNCommunityCoreiOS/SOLARAPI/Providers/NodesProvider/NodesProviderType.swift @@ -18,4 +18,6 @@ public protocol NodesProviderType { _ postNodesRequest: PostNodesByAddressRequest, completion: @escaping (Result, NetworkError>) -> Void ) + + func getCountries(completion: @escaping (Result<[Country], NetworkError>) -> Void) } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj index ef1fdd6..7d8ea00 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj @@ -56,6 +56,7 @@ 923C372028E71D19003CFC03 /* PostNodesByAddressRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C371F28E71D19003CFC03 /* PostNodesByAddressRequest.swift */; }; 923C372228E72C87003CFC03 /* NodesByAddressPostBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C372128E72C87003CFC03 /* NodesByAddressPostBody.swift */; }; 923C372628EAE93E003CFC03 /* Encoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C372528EAE93E003CFC03 /* Encoder.swift */; }; + 923C372828EAF0E8003CFC03 /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C372728EAF0E8003CFC03 /* Country.swift */; }; 92D6B3FD28E19E20004CF9DF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B3FC28E19E20004CF9DF /* AppDelegate.swift */; }; 92D6B3FF28E19E20004CF9DF /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B3FE28E19E20004CF9DF /* SceneDelegate.swift */; }; 92D6B40128E19E20004CF9DF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B40028E19E20004CF9DF /* ViewController.swift */; }; @@ -180,6 +181,7 @@ 923C371F28E71D19003CFC03 /* PostNodesByAddressRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostNodesByAddressRequest.swift; sourceTree = ""; }; 923C372128E72C87003CFC03 /* NodesByAddressPostBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodesByAddressPostBody.swift; sourceTree = ""; }; 923C372528EAE93E003CFC03 /* Encoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encoder.swift; sourceTree = ""; }; + 923C372728EAF0E8003CFC03 /* Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Country.swift; sourceTree = ""; }; 92D6B3F928E19E20004CF9DF /* SOLARdVPNCommunityCoreiOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SOLARdVPNCommunityCoreiOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; 92D6B3FC28E19E20004CF9DF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 92D6B3FE28E19E20004CF9DF /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -529,6 +531,7 @@ 92D6B45B28E46350004CF9DF /* Models */ = { isa = PBXGroup; children = ( + 923C372728EAF0E8003CFC03 /* Country.swift */, 92D6B45C28E4636B004CF9DF /* GetNodesRequest.swift */, 92D6B46228E47240004CF9DF /* Node.swift */, 92D6B46028E463EF004CF9DF /* NodeStatusType.swift */, @@ -841,6 +844,7 @@ 92D6B46328E47240004CF9DF /* Node.swift in Sources */, 92D6B45F28E4639D004CF9DF /* OrderType.swift in Sources */, 92D6B45228E45F03004CF9DF /* NodesProvider.swift in Sources */, + 923C372828EAF0E8003CFC03 /* Country.swift in Sources */, 92D6B44628E34D7C004CF9DF /* APIRequest.swift in Sources */, 92D6B42828E32900004CF9DF /* SOLARAPI.docc in Sources */, 92D6B45A28E46283004CF9DF /* NetworkError.swift in Sources */, diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift index ed56e36..6bf4972 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift @@ -11,8 +11,9 @@ struct NodesRouteCollection: RouteCollection { let context: HasNodesService func boot(routes: RoutesBuilder) throws { - routes.get("nodes", use: getNodes) + routes.get("nodes", use: getNodes) routes.post("nodesByAddress", use: postNodesByAddress) + routes.get("countries", use: getCountries) } } @@ -45,4 +46,8 @@ extension NodesRouteCollection { page: body.page ) } + + func getCountries(_ req: Request) async throws -> String { + try await context.nodesService.getCountries() + } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift index a8aec22..89e0af4 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift @@ -69,4 +69,17 @@ extension NodesService: NodesServiceType { } }) } + + func getCountries() async throws -> String { + try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in + nodesProvider.getCountries() { result in + switch result { + case let .success(response): + Encoder.encode(model: response, continuation: continuation) + case let .failure(error): + continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) + } + } + }) + } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift index c399da5..354e87e 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift @@ -23,4 +23,6 @@ protocol NodesServiceType { by: [String], page: Int? ) async throws -> String + + func getCountries() async throws -> String } From 80c1d4b96169a2bd1a929c752cbea1b86966d186 Mon Sep 17 00:00:00 2001 From: Viktoriia Kostyleva Date: Mon, 3 Oct 2022 14:02:28 +0300 Subject: [PATCH 2/3] Move logic to RouteCollection --- .../Common/Context/CommonContext.swift | 9 +++ .../Common/Context/ContextBuilder.swift | 1 + .../Nodes/NodesRouteCollection.swift | 60 ++++++++++++++----- .../Services/NodesService/NodesService.swift | 60 ------------------- .../NodesService/NodesServiceType.swift | 16 ----- 5 files changed, 55 insertions(+), 91 deletions(-) diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/CommonContext.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/CommonContext.swift index 4af33da..ddad30b 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/CommonContext.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/CommonContext.swift @@ -11,14 +11,23 @@ import SOLARAPI protocol NoContext {} final class CommonContext { + // Providers + let nodesProvider: NodesProviderType + + // Services let nodesService: NodesServiceType init( + nodesProvider: NodesProviderType, nodesService: NodesServiceType ) { + self.nodesProvider = nodesProvider self.nodesService = nodesService } } +protocol HasNodesProvider { var nodesProvider: NodesProviderType { get } } +extension CommonContext: HasNodesProvider {} + protocol HasNodesService { var nodesService: NodesServiceType { get } } extension CommonContext: HasNodesService {} diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/ContextBuilder.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/ContextBuilder.swift index f8b101a..96bf911 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/ContextBuilder.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/ContextBuilder.swift @@ -16,6 +16,7 @@ final class ContextBuilder { let nodesService = NodesService(nodesProvider: nodesProvider) return CommonContext( + nodesProvider: nodesProvider, nodesService: nodesService ) } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift index 6bf4972..4abf670 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift @@ -6,9 +6,10 @@ // import Vapor +import SOLARAPI struct NodesRouteCollection: RouteCollection { - let context: HasNodesService + let context: HasNodesProvider func boot(routes: RoutesBuilder) throws { routes.get("nodes", use: getNodes) @@ -27,27 +28,56 @@ extension NodesRouteCollection { let query = req.query[String.self, at: GetNodesRequest.CodingKeys.query.rawValue] let page = req.query[Int.self, at: GetNodesRequest.CodingKeys.page.rawValue] - return try await context.nodesService.loadNodes( - continentCode: continentCode, - countryCode: countryCode, - minPrice: minPrice, - maxPrice: maxPrice, - orderBy: orderBy, - query: query, - page: page - ) + return try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in + context.nodesProvider.getNodes( + .init( + status: .active, + continentCode: continentCode, + countryCode: countryCode, + minPrice: minPrice, + maxPrice: maxPrice, + orderBy: orderBy, + query: query, + page: page + ) + ) { result in + switch result { + case let .success(response): + Encoder.encode(model: response, continuation: continuation) + case let .failure(error): + continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) + } + } + }) } func postNodesByAddress(_ req: Request) async throws -> String { let body = try req.content.decode(NodesByAddressPostBody.self) - return try await context.nodesService.getNodes( - by: body.blockchain_addresses, - page: body.page - ) + return try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in + context.nodesProvider.postNodesByAddress( + .init(addresses: body.blockchain_addresses, page: body.page) + ) { result in + switch result { + case let .success(response): + Encoder.encode(model: response, continuation: continuation) + case let .failure(error): + continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) + } + } + }) } func getCountries(_ req: Request) async throws -> String { - try await context.nodesService.getCountries() + try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in + context.nodesProvider.getCountries() { result in + switch result { + case let .success(response): + Encoder.encode(model: response, continuation: continuation) + case let .failure(error): + continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) + } + } + }) } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift index 89e0af4..089bc99 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift @@ -22,64 +22,4 @@ final class NodesService { // MARK: - NodesServiceType extension NodesService: NodesServiceType { - func loadNodes( - continentCode: String?, - countryCode: String?, - minPrice: Int?, - maxPrice: Int?, - orderBy: OrderType?, - query: String?, - page: Int? - ) async throws -> String { - try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in - nodesProvider.getNodes( - .init( - status: .active, - continentCode: continentCode, - countryCode: countryCode, - minPrice: minPrice, - maxPrice: maxPrice, - orderBy: orderBy, - query: query, - page: page - ) - ) { result in - switch result { - case let .success(response): - Encoder.encode(model: response, continuation: continuation) - case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) - } - } - }) - } - - func getNodes( - by addresses: [String], - page: Int? - ) async throws -> String { - try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in - nodesProvider.postNodesByAddress(.init(addresses: addresses, page: page)) { result in - switch result { - case let .success(response): - Encoder.encode(model: response, continuation: continuation) - case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) - } - } - }) - } - - func getCountries() async throws -> String { - try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in - nodesProvider.getCountries() { result in - switch result { - case let .success(response): - Encoder.encode(model: response, continuation: continuation) - case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) - } - } - }) - } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift index 354e87e..847c67e 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift @@ -9,20 +9,4 @@ import Foundation import SOLARAPI protocol NodesServiceType { - func loadNodes( - continentCode: String?, - countryCode: String?, - minPrice: Int?, - maxPrice: Int?, - orderBy: OrderType?, - query: String?, - page: Int? - ) async throws -> String - - func getNodes( - by: [String], - page: Int? - ) async throws -> String - - func getCountries() async throws -> String } From 2b27f8dbddcd883d01e8d6b588538ab56920af12 Mon Sep 17 00:00:00 2001 From: Viktoriia Kostyleva Date: Mon, 3 Oct 2022 14:14:19 +0300 Subject: [PATCH 3/3] Add node service functions --- .../project.pbxproj | 4 ++ .../Services/NodesService/NodesService.swift | 60 ++++++++++++++++++- .../NodesService/NodesServiceError.swift | 12 ++++ .../NodesService/NodesServiceType.swift | 12 ++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceError.swift diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj index 7d8ea00..521561b 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj @@ -57,6 +57,7 @@ 923C372228E72C87003CFC03 /* NodesByAddressPostBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C372128E72C87003CFC03 /* NodesByAddressPostBody.swift */; }; 923C372628EAE93E003CFC03 /* Encoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C372528EAE93E003CFC03 /* Encoder.swift */; }; 923C372828EAF0E8003CFC03 /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C372728EAF0E8003CFC03 /* Country.swift */; }; + 923C372A28EAFAA5003CFC03 /* NodesServiceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C372928EAFAA5003CFC03 /* NodesServiceError.swift */; }; 92D6B3FD28E19E20004CF9DF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B3FC28E19E20004CF9DF /* AppDelegate.swift */; }; 92D6B3FF28E19E20004CF9DF /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B3FE28E19E20004CF9DF /* SceneDelegate.swift */; }; 92D6B40128E19E20004CF9DF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B40028E19E20004CF9DF /* ViewController.swift */; }; @@ -182,6 +183,7 @@ 923C372128E72C87003CFC03 /* NodesByAddressPostBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodesByAddressPostBody.swift; sourceTree = ""; }; 923C372528EAE93E003CFC03 /* Encoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encoder.swift; sourceTree = ""; }; 923C372728EAF0E8003CFC03 /* Country.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Country.swift; sourceTree = ""; }; + 923C372928EAFAA5003CFC03 /* NodesServiceError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodesServiceError.swift; sourceTree = ""; }; 92D6B3F928E19E20004CF9DF /* SOLARdVPNCommunityCoreiOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SOLARdVPNCommunityCoreiOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; 92D6B3FC28E19E20004CF9DF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 92D6B3FE28E19E20004CF9DF /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -396,6 +398,7 @@ children = ( 92D6B47228E47EC9004CF9DF /* Models */, 92D6B46E28E47E2E004CF9DF /* NodesService.swift */, + 923C372928EAFAA5003CFC03 /* NodesServiceError.swift */, 92D6B47028E47E71004CF9DF /* NodesServiceType.swift */, ); path = NodesService; @@ -828,6 +831,7 @@ 22C3EEE428E48D9A007DB01B /* NETunnelProviderManager+Ext.swift in Sources */, 22C3EEAA28E4733C007DB01B /* NETunnelProviderProtocol+Extension.swift in Sources */, 22C3EED128E48B52007DB01B /* TunnelStatus.swift in Sources */, + 923C372A28EAFAA5003CFC03 /* NodesServiceError.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift index 089bc99..c9eff2a 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift @@ -7,11 +7,12 @@ import Foundation import SOLARAPI -import Vapor final class NodesService { private let nodesProvider: NodesProviderType + private var loadedNodes: [Node] = [] + init( nodesProvider: NodesProviderType ) { @@ -22,4 +23,61 @@ final class NodesService { // MARK: - NodesServiceType extension NodesService: NodesServiceType { + var nodes: [Node] { + loadedNodes + } + + /// Loads active nodes and saves them to local variable + func loadNodes( + continent: Continent?, + countryCode: String?, + minPrice: Int?, + maxPrice: Int?, + orderBy: OrderType?, + query: String?, + page: Int?, + completion: @escaping (Result, Error>) -> Void + ) { + nodesProvider.getNodes( + .init( + status: .active, + continentCode: continent?.code, + countryCode: countryCode, + minPrice: minPrice, + maxPrice: maxPrice, + orderBy: orderBy, + query: query, + page: page + ) + ) { [weak self] result in + switch result { + case .failure(let error): + log.error(error) + completion(.failure(NodesServiceError.failToLoadData)) + case .success(let response): + completion(.success(response)) + self?.loadedNodes = response.data + } + } + } + + func getNode( + by address: String, + completion: @escaping (Result) -> Void + ) { + nodesProvider.postNodesByAddress(.init(addresses: [address], page: nil)) { result in + switch result { + case .failure(let error): + log.error(error) + completion(.failure(NodesServiceError.failToLoadData)) + case .success(let response): + guard let node = response.data.first else { + completion(.failure(NodesServiceError.failToLoadData)) + return + } + + completion(.success(node)) + } + } + } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceError.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceError.swift new file mode 100644 index 0000000..fb77f1b --- /dev/null +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceError.swift @@ -0,0 +1,12 @@ +// +// NodesServiceError.swift +// SOLARdVPNCommunityCoreiOS +// +// Created by Viktoriia Kostyleva on 03.10.2022. +// + +import Foundation + +enum NodesServiceError: LocalizedError { + case failToLoadData +} diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift index 847c67e..720dab2 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceType.swift @@ -9,4 +9,16 @@ import Foundation import SOLARAPI protocol NodesServiceType { + var nodes: [Node] { get } + func loadNodes( + continent: Continent?, + countryCode: String?, + minPrice: Int?, + maxPrice: Int?, + orderBy: OrderType?, + query: String?, + page: Int?, + completion: @escaping (Result, Error>) -> Void + ) + func getNode(by: String, completion: @escaping (Result) -> Void) }