FieldLocalState.swift (2129B)
1 import Foundation 2 import RadrootsKit 3 4 enum FieldLocalStateError: LocalizedError { 5 case missingBundleIdentifier 6 case invalidLogFileName(String) 7 8 var errorDescription: String? { 9 switch self { 10 case .missingBundleIdentifier: 11 "Missing field iOS bundle identifier." 12 case .invalidLogFileName(let value): 13 "Invalid RADROOTS_FIELD_IOS_LOGGING_FILE_NAME: \(value)." 14 } 15 } 16 } 17 18 enum FieldLocalState { 19 static func roots(bundleIdentifier: String) throws -> RadrootsAppleFileRoots { 20 let appIdentifier = try normalizedBundleIdentifier(bundleIdentifier) 21 return try RadrootsAppleFileRoots.appContainer(appIdentifier: appIdentifier) 22 } 23 24 static func fileAccess(bundleIdentifier: String) throws -> RadrootsAppleFileAccess { 25 try RadrootsAppleFileAccess(roots: roots(bundleIdentifier: bundleIdentifier)) 26 } 27 28 static func logFileURL(bundleIdentifier: String, fileName: String) throws -> URL { 29 let normalizedFileName = try normalizedLogFileName(fileName) 30 let file = RadrootsFileReference(scope: .logs, relativePath: normalizedFileName) 31 return try roots(bundleIdentifier: bundleIdentifier).resolvedURL(for: file) 32 } 33 34 static func resetFileRoots(bundleIdentifier: String) throws { 35 try fileAccess(bundleIdentifier: bundleIdentifier).resetFileRoots() 36 } 37 38 private static func normalizedBundleIdentifier(_ bundleIdentifier: String) throws -> String { 39 let trimmed = bundleIdentifier.trimmingCharacters(in: .whitespacesAndNewlines) 40 guard !trimmed.isEmpty else { 41 throw FieldLocalStateError.missingBundleIdentifier 42 } 43 return trimmed 44 } 45 46 private static func normalizedLogFileName(_ fileName: String) throws -> String { 47 let trimmed = fileName.trimmingCharacters(in: .whitespacesAndNewlines) 48 guard !trimmed.isEmpty, 49 !trimmed.contains("/"), 50 !trimmed.contains("\\"), 51 !trimmed.contains("\0") else { 52 throw FieldLocalStateError.invalidLogFileName(fileName) 53 } 54 return trimmed 55 } 56 }