diff options
Diffstat (limited to 'WireGuard/WireGuard/UI/iOS/RecentTunnelsTracker.swift')
-rw-r--r-- | WireGuard/WireGuard/UI/iOS/RecentTunnelsTracker.swift | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/WireGuard/WireGuard/UI/iOS/RecentTunnelsTracker.swift b/WireGuard/WireGuard/UI/iOS/RecentTunnelsTracker.swift new file mode 100644 index 0000000..787a624 --- /dev/null +++ b/WireGuard/WireGuard/UI/iOS/RecentTunnelsTracker.swift @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. + +import Foundation + +class RecentTunnelsTracker { + + private static let keyRecentlyActivatedTunnelNames = "recentlyActivatedTunnelNames" + private static let maxNumberOfTunnels = 10 + + private static var userDefaults: UserDefaults? { + guard let appGroupId = FileManager.appGroupId else { + wg_log(.error, staticMessage: "Cannot obtain app group ID from bundle for tracking recently used tunnels") + return nil + } + guard let userDefaults = UserDefaults(suiteName: appGroupId) else { + wg_log(.error, staticMessage: "Cannot obtain shared user defaults for tracking recently used tunnels") + return nil + } + return userDefaults + } + + static func handleTunnelActivated(tunnelName: String) { + guard let userDefaults = RecentTunnelsTracker.userDefaults else { return } + var recentTunnels = userDefaults.stringArray(forKey: keyRecentlyActivatedTunnelNames) ?? [] + if let existingIndex = recentTunnels.firstIndex(of: tunnelName) { + recentTunnels.remove(at: existingIndex) + } + recentTunnels.insert(tunnelName, at: 0) + if recentTunnels.count > maxNumberOfTunnels { + recentTunnels.removeLast(recentTunnels.count - maxNumberOfTunnels) + } + userDefaults.set(recentTunnels, forKey: keyRecentlyActivatedTunnelNames) + } + + static func handleTunnelRemoved(tunnelName: String) { + guard let userDefaults = RecentTunnelsTracker.userDefaults else { return } + var recentTunnels = userDefaults.stringArray(forKey: keyRecentlyActivatedTunnelNames) ?? [] + if let existingIndex = recentTunnels.firstIndex(of: tunnelName) { + recentTunnels.remove(at: existingIndex) + userDefaults.set(recentTunnels, forKey: keyRecentlyActivatedTunnelNames) + } + } + + static func handleTunnelRenamed(oldName: String, newName: String) { + guard let userDefaults = RecentTunnelsTracker.userDefaults else { return } + var recentTunnels = userDefaults.stringArray(forKey: keyRecentlyActivatedTunnelNames) ?? [] + if let existingIndex = recentTunnels.firstIndex(of: oldName) { + recentTunnels[existingIndex] = newName + userDefaults.set(recentTunnels, forKey: keyRecentlyActivatedTunnelNames) + } + } + + static func cleanupTunnels(except tunnelNamesToKeep: Set<String>) { + guard let userDefaults = RecentTunnelsTracker.userDefaults else { return } + var recentTunnels = userDefaults.stringArray(forKey: keyRecentlyActivatedTunnelNames) ?? [] + let oldCount = recentTunnels.count + recentTunnels.removeAll { !tunnelNamesToKeep.contains($0) } + if oldCount != recentTunnels.count { + userDefaults.set(recentTunnels, forKey: keyRecentlyActivatedTunnelNames) + } + } + + static func recentlyActivatedTunnelNames(limit: Int) -> [String] { + guard let userDefaults = RecentTunnelsTracker.userDefaults else { return [] } + var recentTunnels = userDefaults.stringArray(forKey: keyRecentlyActivatedTunnelNames) ?? [] + if limit < recentTunnels.count { + recentTunnels.removeLast(recentTunnels.count - limit) + } + return recentTunnels + } +} |