Files
purchases-ios/Sources/Networking/BackendConfiguration.swift
T
Rick 079ce1fd7a fix(remote-config): bind refresh requests to identity clears (#7150)
* fix(remote-config): bind refresh requests to identity clears

* fix(remote-config): require identity-bound cache clears

* perf(remote-config): lazily resolve refresh app user id

* fix(remote-config): pass app user id into refresh

* fix(remote-config): bind refresh user during identity changes

* fix(remote-config): expose refresh parameter test alias

* fix(remote-config): make manager tests Swift 6 safe

* fix(remote-config): address concurrency compile failures

* fix(remote-config): resolve app user id in manager

* fix(remote-config): remove stale workflow cache clear

* fix(remote-config): guard ui config tests for tvos

* fix(remote-config): make workflow test fakes thread-safe

* test: record app user id in receipt mock
2026-07-09 08:27:21 +02:00

89 lines
2.9 KiB
Swift

//
// 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
//
// BackendConfiguration.swift
//
// Created by Joshua Liebowitz on 6/13/22.
import Foundation
class BackendConfiguration {
let httpClient: HTTPClient
let operationDispatcher: OperationDispatcher
let operationQueue: OperationQueue
let diagnosticsQueue: OperationQueue
let dateProvider: DateProvider
let systemInfo: SystemInfo
let offlineCustomerInfoCreator: OfflineCustomerInfoCreator?
init(httpClient: HTTPClient,
operationDispatcher: OperationDispatcher,
operationQueue: OperationQueue,
diagnosticsQueue: OperationQueue,
systemInfo: SystemInfo,
offlineCustomerInfoCreator: OfflineCustomerInfoCreator?,
dateProvider: DateProvider = DateProvider()) {
self.httpClient = httpClient
self.operationDispatcher = operationDispatcher
self.operationQueue = operationQueue
self.diagnosticsQueue = diagnosticsQueue
self.offlineCustomerInfoCreator = offlineCustomerInfoCreator
self.dateProvider = dateProvider
self.systemInfo = systemInfo
}
func clearCache() {
self.httpClient.clearCaches()
}
}
extension BackendConfiguration: NetworkConfiguration {}
extension BackendConfiguration {
/// Adds the `operation` to an `OperationQueue` (based on `CallbackCacheStatus`) potentially adding a random delay.
/// Defaults to the shared serial `operationQueue`; pass a different `queue` to run concurrently off it.
func addCacheableOperation<T: CacheableNetworkOperation>(
with factory: CacheableNetworkOperationFactory<T>,
delay: JitterableDelay,
cacheStatus: CallbackCacheStatus,
queue: OperationQueue? = nil
) {
let targetQueue = SendableOperationQueue(value: queue ?? self.operationQueue)
self.operationDispatcher.dispatchOnWorkerThread(jitterableDelay: delay) {
targetQueue.value.addCacheableOperation(with: factory, cacheStatus: cacheStatus)
}
}
/// Adds the `operation` to the diagnostics `OperationQueue` potentially adding a random delay.
func addDiagnosticsOperation(
_ operation: NetworkOperation,
delay: JitterableDelay = .long
) {
self.operationDispatcher.dispatchOnWorkerThread(jitterableDelay: delay) {
self.diagnosticsQueue.addOperation(operation)
}
}
}
// @unchecked because:
// - `OperationQueue` is not `Sendable` as of Swift 5.7
// - Class is not `final` (it's mocked). This implicitly makes subclasses `Sendable` even if they're not thread-safe.
extension BackendConfiguration: @unchecked Sendable {}
private struct SendableOperationQueue: @unchecked Sendable {
let value: OperationQueue
}