| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- import Foundation
- public struct AirAcceptConfig: Codable, Equatable, Sendable {
- public static let defaultPollIntervalMilliseconds = 2_500
- public var pollIntervalMilliseconds: Int
- public init(
- pollIntervalMilliseconds: Int = Self.defaultPollIntervalMilliseconds
- ) {
- self.pollIntervalMilliseconds = pollIntervalMilliseconds
- }
- private enum CodingKeys: String, CodingKey {
- case pollIntervalMilliseconds = "poll_interval_ms"
- }
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- self.pollIntervalMilliseconds = try container.decodeIfPresent(
- Int.self,
- forKey: .pollIntervalMilliseconds
- ) ?? Self.defaultPollIntervalMilliseconds
- }
- }
- public final class ConfigStore {
- public let configURL: URL
- private let fileManager: FileManager
- public init(
- configURL: URL = ConfigStore.defaultConfigURL(),
- fileManager: FileManager = .default
- ) {
- self.configURL = configURL
- self.fileManager = fileManager
- }
- public static func defaultConfigURL() -> URL {
- let baseURL = FileManager.default.homeDirectoryForCurrentUser
- .appendingPathComponent("Library/Application Support/AirAccept", isDirectory: true)
- return baseURL.appendingPathComponent("config.json", isDirectory: false)
- }
- public func loadOrCreate() throws -> AirAcceptConfig {
- if !fileManager.fileExists(atPath: configURL.path) {
- let config = AirAcceptConfig()
- try save(config)
- return config
- }
- let data = try Data(contentsOf: configURL)
- var config = try JSONDecoder().decode(AirAcceptConfig.self, from: data)
- var shouldSave = false
- if config.pollIntervalMilliseconds == 1_000 {
- config.pollIntervalMilliseconds = AirAcceptConfig.defaultPollIntervalMilliseconds
- shouldSave = true
- }
- if
- let rawConfig = String(data: data, encoding: .utf8),
- rawConfig.contains("dry_run") || rawConfig.contains("fallback_click_visible_airplay_banner")
- {
- shouldSave = true
- }
- if shouldSave {
- try save(config)
- }
- return config
- }
- public func save(_ config: AirAcceptConfig) throws {
- try fileManager.createDirectory(
- at: configURL.deletingLastPathComponent(),
- withIntermediateDirectories: true
- )
- let encoder = JSONEncoder()
- encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
- let data = try encoder.encode(config)
- try data.write(to: configURL, options: [.atomic])
- }
- }
|