From eeeb241f8ac0f7cc30476526a0be45fb2f770cac Mon Sep 17 00:00:00 2001 From: Fabrizio Demaria Date: Fri, 12 Jul 2024 10:49:45 +0200 Subject: [PATCH] docs: Add docs to public APIs --- Sources/Confidence/Confidence.swift | 72 ++++++++++++------- Sources/Confidence/ConfidenceProducer.swift | 6 ++ Sources/Confidence/ConfidenceValue.swift | 1 - .../ConfidenceProviderTest.swift | 9 +-- 4 files changed, 58 insertions(+), 30 deletions(-) diff --git a/Sources/Confidence/Confidence.swift b/Sources/Confidence/Confidence.swift index 29f2b57d..4d63e6cd 100644 --- a/Sources/Confidence/Confidence.swift +++ b/Sources/Confidence/Confidence.swift @@ -1,3 +1,4 @@ +// swiftlint:disable file_length import Foundation import Combine import os @@ -80,7 +81,7 @@ public class Confidence: ConfidenceEventSender { } /** - Fetches latest flag evaluations and store them on disk. Regardless of the fetch outcome (success or failure), this + Fetch latest flag evaluations and store them on disk. Regardless of the fetch outcome (success or failure), this function activates the cache after the fetch. Activating the cache means that the flag data on disk is loaded into memory, so consumers can access flag values. Fetching is best-effort, so no error is propagated. Errors can still be thrown if something goes wrong access data on disk. @@ -97,20 +98,8 @@ public class Confidence: ConfidenceEventSender { try activate() } - func internalFetch() async throws { - let context = getContext() - let resolvedFlags = try await remoteFlagResolver.resolve(ctx: context) - let resolution = FlagResolution( - context: context, - flags: resolvedFlags.resolvedValues, - resolveToken: resolvedFlags.resolveToken ?? "" - ) - debugLogger?.logFlags(action: "Fetch", flag: "") - try storage.save(data: resolution) - } - /** - Fetches latest flag evaluations and store them on disk. Note that "activate" must be called for this data to be + Fetch latest flag evaluations and store them on disk. Note that "activate" must be called for this data to be made available in the app session. */ public func asyncFetch() { @@ -126,6 +115,23 @@ public class Confidence: ConfidenceEventSender { } } + func internalFetch() async throws { + let context = getContext() + let resolvedFlags = try await remoteFlagResolver.resolve(ctx: context) + let resolution = FlagResolution( + context: context, + flags: resolvedFlags.resolvedValues, + resolveToken: resolvedFlags.resolveToken ?? "" + ) + debugLogger?.logFlags(action: "Fetch", flag: "") + try storage.save(data: resolution) + } + + /** + Get evaluation data for a specific flag. Evaluation data includes the variant's name and reason/error information. + - Parameter key:expects dot-notation to retrieve a specific entry in the flag's value, e.g. "flagname.myentry" + - Parameter defaultValue: returned in case of errors or in case of the variant's rule indicating to use the default value. + */ public func getEvaluation(key: String, defaultValue: T) -> Evaluation { self.cache.evaluate( flagName: key, @@ -135,6 +141,11 @@ public class Confidence: ConfidenceEventSender { ) } + /** + Get the value for a specific flag. + - Parameter key:expects dot-notation to retrieve a specific entry in the flag's value, e.g. "flagname.myentry" + - Parameter defaultValue: returned in case of errors or in case of the variant's rule indicating to use the default value. + */ public func getValue(key: String, defaultValue: T) -> T { return getEvaluation(key: key, defaultValue: defaultValue).value } @@ -143,6 +154,9 @@ public class Confidence: ConfidenceEventSender { return storage.isEmpty() } + /** + Listen to changes in the context that is local to this Confidence instance. + */ public func contextChanges() -> AnyPublisher { return contextSubject .dropFirst() @@ -194,15 +208,6 @@ public class Confidence: ConfidenceEventSender { eventSenderEngine.flush() } - private func withLock(callback: @escaping (Confidence) -> Void) { - confidenceQueue.sync { [weak self] in - guard let self = self else { - return - } - callback(self) - } - } - public func getContext() -> ConfidenceStruct { let parentContext = parent?.getContext() ?? [:] var reconciledCtx = parentContext.filter { @@ -270,6 +275,15 @@ public class Confidence: ConfidenceEventSender { parent: self, debugLogger: debugLogger) } + + private func withLock(callback: @escaping (Confidence) -> Void) { + confidenceQueue.sync { [weak self] in + guard let self = self else { + return + } + callback(self) + } + } } extension Confidence { @@ -291,7 +305,8 @@ extension Confidence { internal var debugLogger: DebugLogger? /** - Initializes the builder with the given credentails. + Initialize the builder with the given client secret and logger level. The logger allows to print warnings or + debugging information to the local console. */ public init(clientSecret: String, loggerLevel: LoggerLevel = .WARN) { self.clientSecret = clientSecret @@ -324,13 +339,16 @@ extension Confidence { return self } + /** + Set the initial context. + */ public func withContext(initialContext: ConfidenceStruct) -> Builder { self.initialContext = initialContext return self } /** - Sets the region for the network request to the Confidence backend. + Set the region for the network request to the Confidence backend. The default is `global` and the requests are automatically routed to the closest server. */ public func withRegion(region: ConfidenceRegion) -> Builder { @@ -338,6 +356,9 @@ extension Confidence { return self } + /** + Build the Confidence instance. + */ public func build() -> Confidence { if debugLogger == nil { if loggerLevel != LoggerLevel.NONE { @@ -390,3 +411,4 @@ extension Confidence { } } } +// swiftlint:enable file_length diff --git a/Sources/Confidence/ConfidenceProducer.swift b/Sources/Confidence/ConfidenceProducer.swift index ca6a7dc9..4d3cc200 100644 --- a/Sources/Confidence/ConfidenceProducer.swift +++ b/Sources/Confidence/ConfidenceProducer.swift @@ -23,6 +23,9 @@ public struct Event { ConfidenceContextProducer implementer pushses context changes in a Publisher fashion */ public protocol ConfidenceContextProducer: ConfidenceProducer { + /** + Publish context data. + */ func produceContexts() -> AnyPublisher } @@ -30,5 +33,8 @@ public protocol ConfidenceContextProducer: ConfidenceProducer { ConfidenceContextProducer implementer emit events in a Publisher fashion */ public protocol ConfidenceEventProducer: ConfidenceProducer { + /** + Publish events. + */ func produceEvents() -> AnyPublisher } diff --git a/Sources/Confidence/ConfidenceValue.swift b/Sources/Confidence/ConfidenceValue.swift index 7deaeb6f..9dcbe9ec 100644 --- a/Sources/Confidence/ConfidenceValue.swift +++ b/Sources/Confidence/ConfidenceValue.swift @@ -222,7 +222,6 @@ public enum ConfidenceValueType: CaseIterable { case null } - /// Serializable data structure meant for event sending via Confidence private enum ConfidenceValueInternal: Equatable, Codable { case boolean(Bool) diff --git a/Tests/ConfidenceProviderTests/ConfidenceProviderTest.swift b/Tests/ConfidenceProviderTests/ConfidenceProviderTest.swift index 66140895..d4dfb242 100644 --- a/Tests/ConfidenceProviderTests/ConfidenceProviderTest.swift +++ b/Tests/ConfidenceProviderTests/ConfidenceProviderTest.swift @@ -111,10 +111,11 @@ class ConfidenceProviderTest: XCTestCase { let evaluation = try provider.getIntegerEvaluation(key: "flagName.int", defaultValue: -1, context: context) XCTAssertEqual(evaluation.value, 42) - XCTAssertThrowsError(try provider.getIntegerEvaluation( - key: "flagNotFound.something", - defaultValue: -1, - context: context)) + XCTAssertThrowsError( + try provider.getIntegerEvaluation( + key: "flagNotFound.something", + defaultValue: -1, + context: context)) { error in if let specificError = error as? OpenFeatureError { XCTAssertEqual(specificError.errorCode(), ErrorCode.flagNotFound)