Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vl 6035 #89

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions VCL/VCL.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions VCL/VCL/api/entities/VCLServiceTypeDynamic.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// VCLServiceTypeDynamic.swift
// VCL
//
// Created by Michael Avoyan on 26/10/2023.
//
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0

import Foundation

public struct VCLServiceTypeDynamic {
public let payload: [String: Any]

public init(payload: [String : Any]) {
self.payload = payload
}

public var serviceType: String { get { payload[CodingKeys.KeyServiceType] as? String ?? "" } }
public var serviceCategory: String { get { payload[CodingKeys.KeyServiceCategory] as? String ?? "" } }
public var notary: Bool { get { payload[CodingKeys.KeyNotary] as? Bool ?? false } }
public var credentialGroup: String { get { payload[CodingKeys.KeyCredentialGroup] as? String ?? "" } }

public struct CodingKeys {
public static let KeyServiceType = "serviceType"
public static let KeyServiceCategory = "serviceCategory"
public static let KeyNotary = "notary"
public static let KeyCredentialGroup = "credentialGroup"
}
}
22 changes: 22 additions & 0 deletions VCL/VCL/api/entities/VCLServiceTypesDynamic.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// VCLServiceTypesDynamic.swift
// VCL
//
// Created by Michael Avoyan on 26/10/2023.
//
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0

import Foundation

public struct VCLServiceTypesDynamic {
public let all: [VCLServiceTypeDynamic]

public init(all: [VCLServiceTypeDynamic]) {
self.all = all
}

public struct CodingKeys {
public static let KeyServiceTypes = "serviceTypes"
}
}
18 changes: 17 additions & 1 deletion VCL/VCL/impl/VCLImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@

public class VCLImpl: VCL {

private static let ModelsToInitializeAmount = 3
private static let ModelsToInitializeAmount = 4

private var initializationDescriptor: VCLInitializationDescriptor!

private var credentialTypesModel: CredentialTypesModel!
private var credentialTypeSchemasModel: CredentialTypeSchemasModel!
private var countriesModel: CountriesModel!
private var serviceTypesModel: ServiceTypesModel!

private var presentationRequestUseCase: PresentationRequestUseCase!
private var presentationSubmissionUseCase: PresentationSubmissionUseCase!
Expand Down Expand Up @@ -115,6 +116,8 @@ public class VCLImpl: VCL {

countriesModel = VclBlocksProvider.provideCountriesModel()

serviceTypesModel = VclBlocksProvider.provideServiceTypesModel()

countriesModel.initialize(cacheSequence: cacheSequence) { [weak self] result in
do {
_ = try result.get()
Expand Down Expand Up @@ -158,6 +161,19 @@ public class VCLImpl: VCL {
}
}
}

serviceTypesModel.initialize(cacheSequence: cacheSequence) { [weak self] result in
do {
_ = try result.get()
if self?.initializationWatcher.onInitializedModel(error: nil) == true {
self?.completionHandler(successHandler, errorHandler)
}
} catch {
if self?.initializationWatcher.onInitializedModel(error: error as? VCLError) == true {
self?.completionHandler(successHandler, errorHandler)
}
}
}
}

private func initGlobalConfigurations() {
Expand Down
12 changes: 12 additions & 0 deletions VCL/VCL/impl/VclBlocksProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,18 @@ class VclBlocksProvider {
)
}

static func provideServiceTypesModel() -> ServiceTypesModel {
return ServiceTypesModelImpl(
ServiceTypesUseCaseImpl(
ServiceTypesRepositoryImpl(
NetworkServiceImpl(),
CacheServiceImpl()
),
ExecutorImpl()
)
)
}

static func providePresentationRequestUseCase(
_ cryptoServicesDescriptor: VCLCryptoServicesDescriptor
) throws -> PresentationRequestUseCase {
Expand Down
13 changes: 13 additions & 0 deletions VCL/VCL/impl/data/infrastructure/db/CacheServiceImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class CacheServiceImpl: CacheService {
private static let KEY_CACHE_SEQUENCE_COUNTRIES = "KEY_CACHE_SEQUENCE_COUNTRIES"
private static let KEY_CACHE_SEQUENCE_CREDENTIAL_TYPES = "KEY_CACHE_SEQUENCE_CREDENTIAL_TYPES"
private static let KEY_CACHE_SEQUENCE_CREDENTIAL_TYPE_SCHEMA = "KEY_CACHE_SEQUENCE_CREDENTIAL_TYPE_SCHEMA"
private static let KEY_CACHE_SEQUENCE_SERVICE_TYPES = "KEY_CACHE_SEQUENCE_SERVICE_TYPES"

private var defaults: UserDefaults = UserDefaults()

Expand Down Expand Up @@ -63,4 +64,16 @@ class CacheServiceImpl: CacheService {
func isResetCacheCredentialTypeSchema(cacheSequence: Int) -> Bool {
return getInt(key: CacheServiceImpl.KEY_CACHE_SEQUENCE_CREDENTIAL_TYPE_SCHEMA) < cacheSequence
}

func getServiceTypes(key: String) -> Data? {
return getData(key: key)
}
func setServiceTypes(key: String, value: Data, cacheSequence: Int) {
setData(key: key, value: value)
setInt(key: CacheServiceImpl.KEY_CACHE_SEQUENCE_SERVICE_TYPES, value: cacheSequence)
}
func isResetCacheServiceTypes(cacheSequence: Int) -> Bool {
return getInt(key: CacheServiceImpl.KEY_CACHE_SEQUENCE_SERVICE_TYPES) < cacheSequence
}

}
8 changes: 4 additions & 4 deletions VCL/VCL/impl/data/models/CountriesModelImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import Foundation

class CountriesModelImpl: CountriesModel {

private(set) var data: VCLCountries? = nil
let countriesUseCase: CountriesUseCase

Expand All @@ -23,9 +23,9 @@ class CountriesModelImpl: CountriesModel {
completionBlock: @escaping (VCLResult<VCLCountries>) -> Void
) {
countriesUseCase.getCountries(cacheSequence: cacheSequence) { [weak self] result in
do {
self?.data = try result.get()
} catch {}
do {
self?.data = try result.get()
} catch {}
completionBlock(result)
}
}
Expand Down
4 changes: 2 additions & 2 deletions VCL/VCL/impl/data/models/IdentificationModelImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//
// Created by Michael Avoyan on 18/07/2021.
//
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0

import Foundation

Expand Down
32 changes: 32 additions & 0 deletions VCL/VCL/impl/data/models/ServiceTypesModelImpl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// ServiceTypesModelImpl.swift
// VCL
//
// Created by Michael Avoyan on 29/10/2023.
//
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0

import Foundation

class ServiceTypesModelImpl: ServiceTypesModel {
var data: VCLServiceTypesDynamic?

private let serviceTypesUseCase: ServiceTypesUseCase

init(_ serviceTypesUseCase: ServiceTypesUseCase) {
self.serviceTypesUseCase = serviceTypesUseCase
}

func initialize(
cacheSequence: Int,
completionBlock: @escaping (VCLResult<VCLServiceTypesDynamic>) -> Void
) {
serviceTypesUseCase.getServiceTypes(cacheSequence: cacheSequence) { [weak self] result in
do {
self?.data = try result.get()
} catch {}
completionBlock(result)
}
}
}
86 changes: 86 additions & 0 deletions VCL/VCL/impl/data/repositories/ServiceTypesRepositoryImpl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//
// ServiceTypesRepositoryImpl.swift
// VCL
//
// Created by Michael Avoyan on 26/10/2023.
//

import Foundation

class ServiceTypesRepositoryImpl: ServiceTypesRepository {

private let networkService: NetworkService
private let cacheService: CacheService

init(
_ networkService: NetworkService,
_ cacheService: CacheService) {
self.networkService = networkService
self.cacheService = cacheService
}

func getServiceTypes(
cacheSequence: Int,
completionBlock: @escaping (VCLResult<VCLServiceTypesDynamic>) -> Void
) {
let endpoint = Urls.ServiceTypes
if (cacheService.isResetCacheServiceTypes(cacheSequence: cacheSequence)) {
fetchServiceTypes(endpoint, cacheSequence, completionBlock)
} else {
if let serviceTypesData = cacheService.getServiceTypes(key: endpoint) {
if let serviceTypes = parse(serviceTypesData.toDictionary()) {
completionBlock(.success(serviceTypes))
} else {
completionBlock(.failure(VCLError(message: "Failed to parse \(String(data: serviceTypesData, encoding: .utf8) ?? "")")))
}
} else {
fetchServiceTypes(endpoint, cacheSequence, completionBlock)
}
}
}

private func fetchServiceTypes(
_ endpoint: String,
_ cacheSequence: Int,
_ completionBlock: @escaping (VCLResult<VCLServiceTypesDynamic>) -> Void
) {
networkService.sendRequest(
endpoint: endpoint,
contentType: Request.ContentType.ApplicationJson,
method: Request.HttpMethod.GET,
headers: [(HeaderKeys.XVnfProtocolVersion, HeaderValues.XVnfProtocolVersion)],
completionBlock: { [weak self] result in
do {
let serviceTypesData = try result.get().payload
self?.cacheService.setServiceTypes(
key: endpoint,
value: serviceTypesData,
cacheSequence: cacheSequence
)
if let serviceTypes = self?.parse(serviceTypesData.toDictionary()) {
completionBlock(.success(serviceTypes))
} else {
completionBlock(.failure(VCLError(message: "Failed to parse \(String(data: serviceTypesData, encoding: .utf8) ?? "")")))
}
} catch {
completionBlock(.failure(error as? VCLError ?? VCLError(error: error)))
}
}
)
}

private func parse(_ serviceTypesJsonObj: [String: Any]?) -> VCLServiceTypesDynamic? {
if let serviceTypesJsonArr =
serviceTypesJsonObj?[VCLServiceTypesDynamic.CodingKeys.KeyServiceTypes] as? [Any] {
var serviceTypesArr = [VCLServiceTypeDynamic]()
serviceTypesJsonArr.forEach {
if let payload = $0 as? [String: Any] {
serviceTypesArr.append(VCLServiceTypeDynamic(payload: payload))
}
}
return VCLServiceTypesDynamic(all: serviceTypesArr)
} else {
return nil
}
}
}
1 change: 1 addition & 0 deletions VCL/VCL/impl/data/repositories/Urls.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct Urls {
private static var BaseUrlRegistrar: String { get { "https://\(EnvironmentPrefix)registrar.velocitynetwork.foundation" } }
// private static var BaseUrlWalletApi: String { get { "https://\(EnvironmentPrefix)walletapi.velocitycareerlabs.io" } }

static var ServiceTypes: String { get { "\(BaseUrlRegistrar)/api/v0.6/service-types" } }
static var CredentialTypes: String { get { "\(BaseUrlRegistrar)/api/v0.6/credential-types" } }
static var CredentialTypeSchemas: String { get { "\(BaseUrlRegistrar)/schemas/" } }
static var Countries: String { get { "\(BaseUrlRegistrar)/reference/countries" } }
Expand Down
34 changes: 34 additions & 0 deletions VCL/VCL/impl/data/usecases/ServiceTypesUseCaseImpl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// ServiceTypesUseCaseImpl.swift
// VCL
//
// Created by Michael Avoyan on 29/10/2023.
//
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0

import Foundation

class ServiceTypesUseCaseImpl: ServiceTypesUseCase {
private let serviceTypesRepository: ServiceTypesRepository
private let executor: Executor

init(
_ serviceTypesRepository: ServiceTypesRepository,
_ executor: Executor
) {
self.serviceTypesRepository = serviceTypesRepository
self.executor = executor
}

func getServiceTypes(
cacheSequence: Int,
completionBlock: @escaping (VCLResult<VCLServiceTypesDynamic>) -> Void
) {
executor.runOnBackground { [weak self] in
self?.serviceTypesRepository.getServiceTypes(cacheSequence: cacheSequence) { serviceTypes in
self?.executor.runOnMain { completionBlock(serviceTypes) }
}
}
}
}
4 changes: 4 additions & 0 deletions VCL/VCL/impl/domain/infrastructure/db/CacheService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ protocol CacheService {
func getCredentialTypeSchema(key: String) -> Data?
func setCredentialTypeSchema(key: String, value: Data, cacheSequence: Int)
func isResetCacheCredentialTypeSchema(cacheSequence: Int) -> Bool

func getServiceTypes(key: String) -> Data?
func setServiceTypes(key: String, value: Data, cacheSequence: Int)
func isResetCacheServiceTypes(cacheSequence: Int) -> Bool
}
4 changes: 2 additions & 2 deletions VCL/VCL/impl/domain/models/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//
// Created by Michael Avoyan on 17/03/2021.
//
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0

import Foundation

Expand Down
19 changes: 19 additions & 0 deletions VCL/VCL/impl/domain/models/ServiceTypesModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// ServiceTypesModel.swift
// VCL
//
// Created by Michael Avoyan on 29/10/2023.
//
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0

import Foundation

protocol ServiceTypesModel: Model {
var data: VCLServiceTypesDynamic? { get }

func initialize(
cacheSequence: Int,
completionBlock: @escaping (VCLResult<VCLServiceTypesDynamic>) -> Void
)
}
17 changes: 17 additions & 0 deletions VCL/VCL/impl/domain/repositories/ServiceTypesRepository.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// ServiceTypesRepository.swift
// VCL
//
// Created by Michael Avoyan on 26/10/2023.
//
// Copyright 2022 Velocity Career Labs inc.
// SPDX-License-Identifier: Apache-2.0

import Foundation

protocol ServiceTypesRepository {
func getServiceTypes(
cacheSequence: Int,
completionBlock: @escaping (VCLResult<VCLServiceTypesDynamic>) -> Void
)
}
Loading