aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard/WireGuard/UI/iOS/RecentTunnelsTracker.swift
diff options
context:
space:
mode:
Diffstat (limited to 'WireGuard/WireGuard/UI/iOS/RecentTunnelsTracker.swift')
-rw-r--r--WireGuard/WireGuard/UI/iOS/RecentTunnelsTracker.swift72
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
+ }
+}