-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathXPCCommunicationBridge.swift
More file actions
96 lines (84 loc) · 3.15 KB
/
XPCCommunicationBridge.swift
File metadata and controls
96 lines (84 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import Foundation
import Logger
import AppKit
public enum XPCCommunicationBridgeError: Swift.Error, LocalizedError {
case failedToCreateXPCConnection
case xpcServiceError(Error)
public var errorDescription: String? {
switch self {
case .failedToCreateXPCConnection:
return "Failed to create XPC connection."
case let .xpcServiceError(error):
return "Connection to communication bridge error: \(error.localizedDescription)"
}
}
}
public class XPCCommunicationBridge {
let service: XPCService
let logger: Logger
@XPCServiceActor
var serviceEndpoint: NSXPCListenerEndpoint?
public init(logger: Logger) {
service = .init(
kind: .machService(
identifier: Bundle(for: XPCService.self)
.object(forInfoDictionaryKey: "BUNDLE_IDENTIFIER_BASE") as! String +
".CommunicationBridge"
),
interface: NSXPCInterface(with: CommunicationBridgeXPCServiceProtocol.self),
logger: logger
)
self.logger = logger
}
public func setDelegate(_ delegate: XPCServiceDelegate?) {
service.delegate = delegate
}
@discardableResult
public func launchExtensionServiceIfNeeded() async throws -> NSXPCListenerEndpoint? {
try await withXPCServiceConnected { service, continuation in
service.launchExtensionServiceIfNeeded { endpoint in
continuation.resume(endpoint)
}
}
}
public func quit() async throws {
try await withXPCServiceConnected { service, continuation in
service.quit {
continuation.resume(())
}
}
}
public func updateServiceEndpoint(_ endpoint: NSXPCListenerEndpoint) async throws {
try await withXPCServiceConnected { service, continuation in
service.updateServiceEndpoint(endpoint: endpoint) {
continuation.resume(())
}
}
}
}
extension XPCCommunicationBridge {
@XPCServiceActor
func withXPCServiceConnected<T>(
_ fn: @escaping (CommunicationBridgeXPCServiceProtocol, AutoFinishContinuation<T>) -> Void
) async throws -> T {
guard let connection = service.connection
else { throw XPCCommunicationBridgeError.failedToCreateXPCConnection }
do {
return try await XPCShared.withXPCServiceConnected(connection: connection, fn)
} catch {
throw XPCCommunicationBridgeError.xpcServiceError(error)
}
}
}
public func showBackgroundPermissionAlert() {
let alert = NSAlert()
alert.messageText = "Background Permission Required"
alert.informativeText = "GitHub Copilot for Xcode needs permission to run in the background. Without this permission, features won't work correctly."
alert.alertStyle = .warning
alert.addButton(withTitle: "Open Settings")
alert.addButton(withTitle: "Later")
let response = alert.runModal()
if response == .alertFirstButtonReturn {
NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.LoginItems-Settings.extension")!)
}
}