diff --git a/ApplicationLibrary/Views/Setting/SettingView.swift b/ApplicationLibrary/Views/Setting/SettingView.swift index 5651489..121f29d 100644 --- a/ApplicationLibrary/Views/Setting/SettingView.swift +++ b/ApplicationLibrary/Views/Setting/SettingView.swift @@ -101,8 +101,19 @@ public struct SettingView: View { Task { do { if let result = try await SystemExtension.install(forceUpdate: true) { - if result == .willCompleteAfterReboot { - alert = Alert(errorMessage: "Need reboot") + switch result { + case .completed: + alert = Alert( + title: Text("Update"), + message: Text("System Extension updated."), + dismissButton: .default(Text("Ok")) {} + ) + case .willCompleteAfterReboot: + alert = Alert( + title: Text("Update"), + message: Text("Reboot required."), + dismissButton: .default(Text("Ok")) {} + ) } } } catch { @@ -110,6 +121,32 @@ public struct SettingView: View { } } } + Button { + Task { + do { + if let result = try await SystemExtension.uninstall() { + switch result { + case .completed: + alert = Alert( + title: Text("Uninstall"), + message: Text("System Extension removed."), + dismissButton: .default(Text("Ok")) {} + ) + case .willCompleteAfterReboot: + alert = Alert( + title: Text("Uninstall"), + message: Text("Reboot required."), + dismissButton: .default(Text("Ok")) {} + ) + } + } + } catch { + alert = Alert(error) + } + } + } label: { + Text("Uninstall System Extension").foregroundColor(.red) + } }.frame(maxWidth: .infinity, alignment: .trailing) } #endif diff --git a/Library/Network/SystemExtension.swift b/Library/Network/SystemExtension.swift index 3e3a50f..43267d7 100644 --- a/Library/Network/SystemExtension.swift +++ b/Library/Network/SystemExtension.swift @@ -10,7 +10,7 @@ private var properties: [OSSystemExtensionProperties]? private var error: Error? - private init(forceUpdate: Bool = false, inBackground: Bool = false) { + private init(_ forceUpdate: Bool = false, _ inBackground: Bool = false) { self.forceUpdate = forceUpdate self.inBackground = inBackground } @@ -53,7 +53,7 @@ semaphore.signal() } - public func submitAndWait() throws -> OSSystemExtensionRequest.Result? { + public func activation() throws -> OSSystemExtensionRequest.Result? { let request = OSSystemExtensionRequest.activationRequest(forExtensionWithIdentifier: FilePath.packageName + ".system", queue: .main) request.delegate = self OSSystemExtensionManager.shared.submitRequest(request) @@ -64,6 +64,17 @@ return result } + public func deactivation() throws -> OSSystemExtensionRequest.Result? { + let request = OSSystemExtensionRequest.deactivationRequest(forExtensionWithIdentifier: FilePath.packageName + ".system", queue: .main) + request.delegate = self + OSSystemExtensionManager.shared.submitRequest(request) + semaphore.wait() + if let error { + throw error + } + return result + } + public func getProperties() throws -> [OSSystemExtensionProperties] { let request = OSSystemExtensionRequest.propertiesRequest(forExtensionWithIdentifier: FilePath.packageName + ".system", queue: .main) request.delegate = self @@ -100,9 +111,15 @@ return false } - public static func install(forceUpdate: Bool = false, inBackground _: Bool = false) async throws -> OSSystemExtensionRequest.Result? { + public static func install(forceUpdate: Bool = false, inBackground: Bool = false) async throws -> OSSystemExtensionRequest.Result? { + try await Task.detached { + try SystemExtension(forceUpdate, inBackground).activation() + }.result.get() + } + + public static func uninstall() async throws -> OSSystemExtensionRequest.Result? { try await Task.detached { - try SystemExtension(forceUpdate: forceUpdate).submitAndWait() + try SystemExtension().deactivation() }.result.get() } } diff --git a/README.md b/README.md index eaae019..01a719d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Experimental iOS/macOS/tvOS client for sing-box, the universal proxy platform. ## Documentation -[SFI](https://sing-box.sagernet.org/installation/clients/sfi/) | [SFM](https://sing-box.sagernet.org/installation/clients/sfm/) +[sing-box for Apple platforms](https://sing-box.sagernet.org/clients/apple/) ## License @@ -23,4 +23,4 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -``` \ No newline at end of file +```