72 lines
2.1 KiB
Swift
72 lines
2.1 KiB
Swift
import Foundation
|
|
import NetworkExtension
|
|
|
|
enum WidgetAppConfiguration {
|
|
static let packageName: String = {
|
|
guard let value = Bundle.main.object(forInfoDictionaryKey: "BasePackageIdentifier") as? String else {
|
|
fatalError("Missing BasePackageIdentifier in Info.plist")
|
|
}
|
|
return value
|
|
}()
|
|
|
|
static let appGroupID: String = {
|
|
guard let value = Bundle.main.object(forInfoDictionaryKey: "AppGroupIdentifier") as? String else {
|
|
fatalError("Missing AppGroupIdentifier in Info.plist")
|
|
}
|
|
return value
|
|
}()
|
|
|
|
static var widgetControlKind: String {
|
|
"\(packageName).widget.ServiceToggle"
|
|
}
|
|
}
|
|
|
|
extension NEVPNStatus {
|
|
var isStarted: Bool {
|
|
switch self {
|
|
case .connecting, .connected, .reasserting:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
enum WidgetTunnelControl {
|
|
static func currentIsStarted() async throws -> Bool {
|
|
guard let manager = try await loadManager() else {
|
|
return false
|
|
}
|
|
return manager.connection.status.isStarted
|
|
}
|
|
|
|
static func setStarted(_ started: Bool) async throws {
|
|
guard let manager = try await loadManager() else {
|
|
NSLog("[WidgetTunnelControl] No tunnel configuration found")
|
|
throw NSError(domain: "WidgetTunnelControl", code: 1, userInfo: [
|
|
NSLocalizedDescriptionKey: "Tunnel configuration not found",
|
|
])
|
|
}
|
|
|
|
if started {
|
|
if manager.isEnabled == false {
|
|
manager.isEnabled = true
|
|
try await manager.saveToPreferences()
|
|
}
|
|
do {
|
|
try manager.connection.startVPNTunnel()
|
|
} catch {
|
|
NSLog("[WidgetTunnelControl] startVPNTunnel failed: \(error.localizedDescription)")
|
|
throw error
|
|
}
|
|
} else {
|
|
manager.connection.stopVPNTunnel()
|
|
}
|
|
}
|
|
|
|
private static func loadManager() async throws -> NETunnelProviderManager? {
|
|
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
|
|
return managers.first
|
|
}
|
|
}
|