add swiftUI code
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
#if os(macOS)
|
||||
import Foundation
|
||||
import SystemExtensions
|
||||
|
||||
public class SystemExtension: NSObject, OSSystemExtensionRequestDelegate {
|
||||
private let forceUpdate: Bool
|
||||
private let inBackground: Bool
|
||||
private let semaphore = DispatchSemaphore(value: 0)
|
||||
private var result: OSSystemExtensionRequest.Result?
|
||||
private var properties: [OSSystemExtensionProperties]?
|
||||
private var error: Error?
|
||||
|
||||
private init(_ forceUpdate: Bool = false, _ inBackground: Bool = false) {
|
||||
self.forceUpdate = forceUpdate
|
||||
self.inBackground = inBackground
|
||||
}
|
||||
|
||||
public func request(_: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) -> OSSystemExtensionRequest.ReplacementAction {
|
||||
if forceUpdate {
|
||||
return .replace
|
||||
}
|
||||
if existing.isAwaitingUserApproval, !inBackground {
|
||||
return .replace
|
||||
}
|
||||
if existing.bundleIdentifier == ext.bundleIdentifier,
|
||||
existing.bundleVersion == ext.bundleVersion,
|
||||
existing.bundleShortVersion == ext.bundleShortVersion
|
||||
{
|
||||
NSLog("Skip update system extension")
|
||||
return .cancel
|
||||
} else {
|
||||
NSLog("Update system extension")
|
||||
return .replace
|
||||
}
|
||||
}
|
||||
|
||||
public func requestNeedsUserApproval(_: OSSystemExtensionRequest) {
|
||||
semaphore.signal()
|
||||
}
|
||||
|
||||
public func request(_: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) {
|
||||
self.result = result
|
||||
semaphore.signal()
|
||||
}
|
||||
|
||||
public func request(_: OSSystemExtensionRequest, didFailWithError error: Error) {
|
||||
self.error = error
|
||||
semaphore.signal()
|
||||
}
|
||||
|
||||
public func request(_: OSSystemExtensionRequest, foundProperties properties: [OSSystemExtensionProperties]) {
|
||||
self.properties = properties
|
||||
semaphore.signal()
|
||||
}
|
||||
|
||||
public func activation() throws -> OSSystemExtensionRequest.Result? {
|
||||
let request = OSSystemExtensionRequest.activationRequest(forExtensionWithIdentifier: FilePath.packageName + ".system", queue: .main)
|
||||
request.delegate = self
|
||||
OSSystemExtensionManager.shared.submitRequest(request)
|
||||
semaphore.wait()
|
||||
if let error {
|
||||
throw error
|
||||
}
|
||||
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
|
||||
OSSystemExtensionManager.shared.submitRequest(request)
|
||||
semaphore.wait()
|
||||
if let error {
|
||||
throw error
|
||||
}
|
||||
return properties!
|
||||
}
|
||||
|
||||
public static func isInstalled() async -> Bool {
|
||||
await (try? Task {
|
||||
try await isInstalledBackground()
|
||||
}.result.get()) == true
|
||||
}
|
||||
|
||||
public nonisolated static func isInstalledBackground() async throws -> Bool {
|
||||
for _ in 0 ..< 3 {
|
||||
do {
|
||||
let propList = try SystemExtension().getProperties()
|
||||
if propList.isEmpty {
|
||||
return false
|
||||
}
|
||||
for extensionProp in propList {
|
||||
if !extensionProp.isAwaitingUserApproval, !extensionProp.isUninstalling {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
try await Task.sleep(nanoseconds: NSEC_PER_SEC)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public nonisolated 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 nonisolated static func uninstall() async throws -> OSSystemExtensionRequest.Result? {
|
||||
try await Task.detached {
|
||||
try SystemExtension().deactivation()
|
||||
}.result.get()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user