// // Copyright RevenueCat Inc. All Rights Reserved. // // Licensed under the MIT License (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://opensource.org/licenses/MIT // // InternalAPI.swift // // Created by Nacho Soto on 10/5/22. import Foundation final class InternalAPI { typealias ResponseHandler = (BackendError?) -> Void private let backendConfig: BackendConfiguration private let callbackCache: CallbackCache init(backendConfig: BackendConfiguration) { self.backendConfig = backendConfig self.callbackCache = .init() } func healthRequest(signatureVerification: Bool, completion: @escaping ResponseHandler) { let factory = HealthOperation.createFactory(httpClient: self.backendConfig.httpClient, callbackCache: self.callbackCache, signatureVerification: signatureVerification) let callback = HealthOperation.Callback(cacheKey: factory.cacheKey, completion: completion) let cacheStatus = self.callbackCache.add(callback) self.backendConfig.addCacheableOperation(with: factory, withRandomDelay: false, cacheStatus: cacheStatus) } } // MARK: - Health private final class HealthOperation: CacheableNetworkOperation { struct Callback: CacheKeyProviding { let cacheKey: String let completion: InternalAPI.ResponseHandler } struct Configuration: NetworkConfiguration { let httpClient: HTTPClient } private let callbackCache: CallbackCache private let signatureVerification: Bool static func createFactory( httpClient: HTTPClient, callbackCache: CallbackCache, signatureVerification: Bool ) -> CacheableNetworkOperationFactory { return .init({ .init(httpClient: httpClient, callbackCache: callbackCache, cacheKey: $0, signatureVerification: signatureVerification) }, individualizedCacheKeyPart: "") } private init(httpClient: HTTPClient, callbackCache: CallbackCache, cacheKey: String, signatureVerification: Bool) { self.callbackCache = callbackCache self.signatureVerification = signatureVerification super.init(configuration: Configuration(httpClient: httpClient), cacheKey: cacheKey) } override func begin(completion: @escaping () -> Void) { let request: HTTPRequest = .init(method: .get, path: .health) self.httpClient.perform( request, with: self.verificationMode ) { (response: HTTPResponse.Result) in self.finish(with: response, completion: completion) } } private func finish(with response: HTTPResponse.Result, completion: () -> Void) { self.callbackCache.performOnAllItemsAndRemoveFromCache(withCacheable: self) { callback in callback.completion( response .mapError(BackendError.networkError) .error ) } completion() } private var verificationMode: Signing.ResponseVerificationMode { if self.signatureVerification, #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *) { return Signing.verificationMode(with: .enforced) } else { return .disabled } } }