WarplyConfiguration.swift
14.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
//
// WarplyConfiguration.swift
// SwiftWarplyFramework
//
// Created by Warply on 25/6/25.
//
import Foundation
/// Main configuration container for the SwiftWarplyFramework
/// Provides comprehensive control over all framework behavior including security, performance, and logging
public struct WarplyConfiguration {
// MARK: - Component Configurations
/// Database and encryption configuration
public var databaseConfig: WarplyDatabaseConfig = WarplyDatabaseConfig()
/// Token refresh and authentication configuration
public var tokenConfig: WarplyTokenConfig = WarplyTokenConfig()
/// Logging and debugging configuration
public var loggingConfig: WarplyLoggingConfig = WarplyLoggingConfig()
/// Network and connectivity configuration
public var networkConfig: WarplyNetworkConfig = WarplyNetworkConfig()
// MARK: - Global Framework Settings
/// Enable analytics event collection and reporting
public var enableAnalytics: Bool = true
/// Enable crash reporting and error analytics
public var enableCrashReporting: Bool = false
/// Enable automatic device registration on SDK initialization
public var enableAutoRegistration: Bool = true
/// Framework version for compatibility tracking
public let frameworkVersion: String = "2.5.1"
// MARK: - Initialization
/// Creates a new configuration with default settings
/// All defaults are production-ready and secure
public init() {}
// MARK: - Validation
/// Validates all configuration components
/// - Throws: ConfigurationError if any configuration is invalid
public func validate() throws {
try databaseConfig.validate()
try tokenConfig.validate()
try loggingConfig.validate()
try networkConfig.validate()
print("✅ [WarplyConfiguration] All configuration components validated successfully")
}
// MARK: - Configuration Summary
/// Returns a summary of the current configuration for debugging
/// - Returns: Dictionary with configuration summary (no sensitive data)
public func getSummary() -> [String: Any] {
return [
"frameworkVersion": frameworkVersion,
"enableAnalytics": enableAnalytics,
"enableCrashReporting": enableCrashReporting,
"enableAutoRegistration": enableAutoRegistration,
"database": databaseConfig.getSummary(),
"token": tokenConfig.getSummary(),
"logging": loggingConfig.getSummary(),
"network": networkConfig.getSummary()
]
}
}
// MARK: - Preset Configurations
extension WarplyConfiguration {
/// Development configuration with verbose logging and debugging features
/// - Encryption disabled for easier debugging
/// - Verbose logging enabled
/// - All debugging features enabled
public static var development: WarplyConfiguration {
var config = WarplyConfiguration()
// Development-friendly database settings
config.databaseConfig.encryptionEnabled = false
config.databaseConfig.enableWALMode = true
config.databaseConfig.cacheSize = 1000
// Verbose logging for debugging
config.loggingConfig.logLevel = .verbose
config.loggingConfig.enableDatabaseLogging = true
config.loggingConfig.enableNetworkLogging = true
config.loggingConfig.enableTokenLogging = true
config.loggingConfig.enablePerformanceLogging = true
config.loggingConfig.maskSensitiveData = false // Show full data in development
// Faster timeouts for development
config.networkConfig.requestTimeout = 15.0
config.networkConfig.maxRetryAttempts = 2
// Reduced token retry for faster development cycles
config.tokenConfig.maxRetryAttempts = 2
config.tokenConfig.retryDelays = [0.0, 1.0]
print("🔧 [WarplyConfiguration] Development configuration loaded")
return config
}
/// Production configuration with security and performance optimizations
/// - Encryption enabled by default
/// - Minimal logging for performance
/// - Conservative retry policies
public static var production: WarplyConfiguration {
var config = WarplyConfiguration()
// Production security settings
config.databaseConfig.encryptionEnabled = true
config.databaseConfig.dataProtectionClass = .complete
config.databaseConfig.enableWALMode = true
config.databaseConfig.cacheSize = 2000
// Minimal logging for performance
config.loggingConfig.logLevel = .warning
config.loggingConfig.enableDatabaseLogging = false
config.loggingConfig.enableNetworkLogging = false
config.loggingConfig.enableTokenLogging = false
config.loggingConfig.enablePerformanceLogging = false
config.loggingConfig.maskSensitiveData = true
// Production network settings
config.networkConfig.requestTimeout = 30.0
config.networkConfig.maxRetryAttempts = 3
config.networkConfig.enableExponentialBackoff = true
// Standard token refresh settings
config.tokenConfig.maxRetryAttempts = 3
config.tokenConfig.retryDelays = [0.0, 1.0, 5.0]
config.tokenConfig.circuitBreakerThreshold = 5
// Enable crash reporting in production
config.enableCrashReporting = true
print("🏭 [WarplyConfiguration] Production configuration loaded")
return config
}
/// Testing configuration optimized for unit and integration tests
/// - Minimal logging to reduce test noise
/// - Fast timeouts for quick test execution
/// - Reduced retry attempts
public static var testing: WarplyConfiguration {
var config = WarplyConfiguration()
// Testing database settings
config.databaseConfig.encryptionEnabled = false
config.databaseConfig.enableWALMode = false
config.databaseConfig.cacheSize = 500
// Minimal logging for clean test output
config.loggingConfig.logLevel = .error
config.loggingConfig.enableDatabaseLogging = false
config.loggingConfig.enableNetworkLogging = false
config.loggingConfig.enableTokenLogging = false
config.loggingConfig.enablePerformanceLogging = false
// Fast timeouts for quick tests
config.networkConfig.requestTimeout = 5.0
config.networkConfig.resourceTimeout = 10.0
config.networkConfig.maxRetryAttempts = 1
config.networkConfig.retryDelay = 0.1
config.networkConfig.enableExponentialBackoff = false
// Minimal token retry for fast tests
config.tokenConfig.maxRetryAttempts = 1
config.tokenConfig.retryDelays = [0.0]
config.tokenConfig.refreshThresholdMinutes = 1
config.tokenConfig.circuitBreakerThreshold = 2
// Disable analytics in tests
config.enableAnalytics = false
config.enableCrashReporting = false
config.enableAutoRegistration = false
print("🧪 [WarplyConfiguration] Testing configuration loaded")
return config
}
/// High-security configuration for sensitive environments
/// - Maximum encryption and security features
/// - Minimal logging to prevent data leakage
/// - Conservative network policies
public static var highSecurity: WarplyConfiguration {
var config = WarplyConfiguration()
// Maximum security database settings
config.databaseConfig.encryptionEnabled = true
config.databaseConfig.dataProtectionClass = .completeUntilFirstUserAuthentication
config.databaseConfig.useKeychainForKeys = true
config.databaseConfig.enableWALMode = true
// Minimal logging for security
config.loggingConfig.logLevel = .error
config.loggingConfig.enableDatabaseLogging = false
config.loggingConfig.enableNetworkLogging = false
config.loggingConfig.enableTokenLogging = false
config.loggingConfig.enablePerformanceLogging = false
config.loggingConfig.maskSensitiveData = true
config.loggingConfig.enableFileLogging = false
// Conservative network settings
config.networkConfig.requestTimeout = 20.0
config.networkConfig.maxRetryAttempts = 2
config.networkConfig.allowsCellularAccess = false // WiFi only
// Conservative token settings
config.tokenConfig.refreshThresholdMinutes = 10 // Refresh earlier
config.tokenConfig.maxRetryAttempts = 2
config.tokenConfig.retryDelays = [0.0, 2.0]
config.tokenConfig.circuitBreakerThreshold = 3
// Disable optional features for security
config.enableCrashReporting = false
print("🔒 [WarplyConfiguration] High-security configuration loaded")
return config
}
}
// MARK: - Codable Support
extension WarplyConfiguration: Codable {
// Custom coding keys to exclude frameworkVersion from Codable
private enum CodingKeys: String, CodingKey {
case databaseConfig
case tokenConfig
case loggingConfig
case networkConfig
case enableAnalytics
case enableCrashReporting
case enableAutoRegistration
// frameworkVersion is excluded - it's a constant that shouldn't be encoded/decoded
}
/// Saves configuration to JSON data
/// - Returns: JSON data representation of the configuration
/// - Throws: EncodingError if serialization fails
public func toJSONData() throws -> Data {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
return try encoder.encode(self)
}
/// Creates configuration from JSON data
/// - Parameter data: JSON data containing configuration
/// - Returns: WarplyConfiguration instance
/// - Throws: DecodingError if deserialization fails
public static func fromJSONData(_ data: Data) throws -> WarplyConfiguration {
let decoder = JSONDecoder()
return try decoder.decode(WarplyConfiguration.self, from: data)
}
/// Saves configuration to file
/// - Parameter url: File URL to save configuration
/// - Throws: Error if file writing fails
public func saveToFile(at url: URL) throws {
let data = try toJSONData()
try data.write(to: url)
print("💾 [WarplyConfiguration] Configuration saved to: \(url.path)")
}
/// Loads configuration from file
/// - Parameter url: File URL to load configuration from
/// - Returns: WarplyConfiguration instance
/// - Throws: Error if file reading or parsing fails
public static func loadFromFile(at url: URL) throws -> WarplyConfiguration {
let data = try Data(contentsOf: url)
let config = try fromJSONData(data)
print("📂 [WarplyConfiguration] Configuration loaded from: \(url.path)")
return config
}
}
// MARK: - Configuration Errors
/// Errors that can occur during configuration validation or processing
public enum ConfigurationError: Error, LocalizedError {
case invalidRefreshThreshold(Int)
case invalidRetryAttempts(Int)
case retryDelaysMismatch(expected: Int, actual: Int)
case invalidLogLevel(String)
case invalidTimeout(TimeInterval)
case invalidKeyIdentifier(String)
case invalidCacheSize(Int)
case invalidCircuitBreakerThreshold(Int)
case invalidFileSize(Int)
case configurationValidationFailed([String])
public var errorDescription: String? {
switch self {
case .invalidRefreshThreshold(let minutes):
return "Invalid refresh threshold: \(minutes) minutes. Must be between 1 and 60 minutes."
case .invalidRetryAttempts(let attempts):
return "Invalid retry attempts: \(attempts). Must be between 1 and 10 attempts."
case .retryDelaysMismatch(let expected, let actual):
return "Retry delays count mismatch: expected \(expected) delays, got \(actual)."
case .invalidLogLevel(let level):
return "Invalid log level: \(level). Must be a valid WarplyLogLevel."
case .invalidTimeout(let timeout):
return "Invalid timeout: \(timeout) seconds. Must be between 1 and 300 seconds."
case .invalidKeyIdentifier(let identifier):
return "Invalid key identifier: \(identifier). Must be a non-empty string."
case .invalidCacheSize(let size):
return "Invalid cache size: \(size). Must be between 100 and 10000."
case .invalidCircuitBreakerThreshold(let threshold):
return "Invalid circuit breaker threshold: \(threshold). Must be between 1 and 20."
case .invalidFileSize(let size):
return "Invalid file size: \(size) bytes. Must be between 1MB and 100MB."
case .configurationValidationFailed(let errors):
return "Configuration validation failed with errors: \(errors.joined(separator: ", "))"
}
}
public var recoverySuggestion: String? {
switch self {
case .invalidRefreshThreshold:
return "Use a refresh threshold between 1 and 60 minutes. Recommended: 5 minutes."
case .invalidRetryAttempts:
return "Use between 1 and 10 retry attempts. Recommended: 3 attempts."
case .retryDelaysMismatch:
return "Ensure the retry delays array has the same count as maxRetryAttempts."
case .invalidLogLevel:
return "Use one of: .none, .error, .warning, .info, .debug, .verbose"
case .invalidTimeout:
return "Use a timeout between 1 and 300 seconds. Recommended: 30 seconds."
case .invalidKeyIdentifier:
return "Provide a non-empty string for the key identifier."
case .invalidCacheSize:
return "Use a cache size between 100 and 10000. Recommended: 2000."
case .invalidCircuitBreakerThreshold:
return "Use a threshold between 1 and 20. Recommended: 5."
case .invalidFileSize:
return "Use a file size between 1MB and 100MB. Recommended: 10MB."
case .configurationValidationFailed:
return "Fix all validation errors and try again."
}
}
}