diff --git a/TunnelKit/Sources/AppExtension/MemoryDestination.swift b/TunnelKit/Sources/AppExtension/MemoryDestination.swift index 4630a23..973c795 100644 --- a/TunnelKit/Sources/AppExtension/MemoryDestination.swift +++ b/TunnelKit/Sources/AppExtension/MemoryDestination.swift @@ -54,11 +54,11 @@ class MemoryDestination: BaseDestination, CustomStringConvertible { } } - func flush(to: UserDefaults, with key: String) { + func flush(to url: URL) { execute(synchronously: true) { - to.set(self.buffer, forKey: key) + let content = self.buffer.joined(separator: "\n") + try? content.write(to: url, atomically: true, encoding: .utf8) } - to.synchronize() } var description: String { diff --git a/TunnelKit/Sources/AppExtension/TunnelKitProvider+Configuration.swift b/TunnelKit/Sources/AppExtension/TunnelKitProvider+Configuration.swift index 8b9b297..1489e38 100644 --- a/TunnelKit/Sources/AppExtension/TunnelKitProvider+Configuration.swift +++ b/TunnelKit/Sources/AppExtension/TunnelKitProvider+Configuration.swift @@ -159,7 +159,7 @@ extension TunnelKitProvider { /// Enables debugging. If `true`, then `debugLogKey` is a mandatory field. public var shouldDebug: Bool - /// The key in `defaults` where the latest debug log snapshot is stored. Ignored if `shouldDebug` is `false`. + /// The filename in group container where the latest debug log snapshot is stored. Ignored if `shouldDebug` is `false`. public var debugLogKey: String? /// Optional debug log format (SwiftyBeaver format). @@ -403,12 +403,22 @@ extension TunnelKitProvider { public let lastErrorKey: String? // MARK: Shortcuts - - func existingLog(in defaults: UserDefaults) -> [String]? { + + func urlForLog(in appGroup: String) -> URL? { guard shouldDebug, let key = debugLogKey else { return nil } - return defaults.array(forKey: key) as? [String] + guard let parentURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else { + return nil + } + return parentURL.appendingPathComponent("\(key).log") + } + + func existingLog(in appGroup: String) -> String? { + guard let url = urlForLog(in: appGroup) else { + return nil + } + return try? String(contentsOf: url) } // MARK: API diff --git a/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift b/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift index a8c3594..35e867c 100644 --- a/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift +++ b/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift @@ -94,12 +94,12 @@ open class TunnelKitProvider: NEPacketTunnelProvider { private var appGroup: String! + private lazy var defaults = UserDefaults(suiteName: appGroup) + private var cfg: Configuration! private var strategy: ConnectionStrategy! - private lazy var defaults = UserDefaults(suiteName: appGroup) - // MARK: Internal state private var proxy: SessionProxy? @@ -157,7 +157,8 @@ open class TunnelKitProvider: NEPacketTunnelProvider { strategy = ConnectionStrategy(hostname: hostname, configuration: cfg) - if let defaults = defaults, var existingLog = cfg.existingLog(in: defaults) { + if let content = cfg.existingLog(in: appGroup) { + var existingLog = content.components(separatedBy: "\n") if let i = existingLog.index(of: logSeparator) { existingLog.removeFirst(i + 2) } @@ -595,8 +596,8 @@ extension TunnelKitProvider { private func flushLog() { log.debug("Flushing log...") - if let defaults = defaults, let key = cfg.debugLogKey { - memoryLog.flush(to: defaults, with: key) + if let url = cfg.urlForLog(in: appGroup) { + memoryLog.flush(to: url) } }