Skip to content

Commit 7e20626

Browse files
committed
Move XPC related content to XPCController
1 parent bff6f26 commit 7e20626

File tree

2 files changed

+62
-11
lines changed

2 files changed

+62
-11
lines changed

ExtensionService/AppDelegate.swift

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import UpdateChecker
1010
import UserDefaultsObserver
1111
import UserNotifications
1212
import XcodeInspector
13+
import XPCShared
1314

1415
let bundleIdentifierBase = Bundle.main
1516
.object(forInfoDictionaryKey: "BUNDLE_IDENTIFIER_BASE") as! String
@@ -19,7 +20,7 @@ let serviceIdentifier = bundleIdentifierBase + ".ExtensionService"
1920
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
2021
let service = Service.shared
2122
var statusBarItem: NSStatusItem!
22-
var xpcListener: (NSXPCListener, ServiceDelegate)?
23+
var xpcController: XPCController?
2324
let updateChecker =
2425
UpdateChecker(
2526
hostBundle: locateHostBundleURL(url: Bundle.main.bundleURL)
@@ -35,7 +36,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
3536
] as CFDictionary)
3637
setupQuitOnUpdate()
3738
setupQuitOnUserTerminated()
38-
xpcListener = setupXPCListener()
39+
xpcController = .init()
3940
Logger.service.info("XPC Service started.")
4041
NSApp.setActivationPolicy(.accessory)
4142
buildStatusBarMenu()
@@ -48,7 +49,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
4849
}
4950
}
5051
}
51-
52+
5253
@objc func quit() {
5354
Task { @MainActor in
5455
await service.prepareForExit()
@@ -125,14 +126,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
125126
}
126127
}
127128

128-
func setupXPCListener() -> (NSXPCListener, ServiceDelegate) {
129-
let listener = NSXPCListener(machServiceName: serviceIdentifier)
130-
let delegate = ServiceDelegate()
131-
listener.delegate = delegate
132-
listener.resume()
133-
return (listener, delegate)
134-
}
135-
136129
func requestAccessoryAPIPermission() {
137130
AXIsProcessTrustedWithOptions([
138131
kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import Foundation
2+
import Logger
3+
import XPCShared
4+
5+
final class XPCController: XPCServiceDelegate {
6+
let bridge: XPCCommunicationBridge
7+
let xpcListener: NSXPCListener
8+
let xpcServiceDelegate: ServiceDelegate
9+
10+
var pingTask: Task<Void, Error>?
11+
12+
init() {
13+
let bridge = XPCCommunicationBridge(logger: .client)
14+
let listener = NSXPCListener.anonymous()
15+
let delegate = ServiceDelegate()
16+
listener.delegate = delegate
17+
listener.resume()
18+
xpcListener = listener
19+
xpcServiceDelegate = delegate
20+
self.bridge = bridge
21+
22+
Task {
23+
await bridge.setDelegate(self)
24+
createPingTask()
25+
}
26+
}
27+
28+
deinit {
29+
xpcListener.invalidate()
30+
pingTask?.cancel()
31+
}
32+
33+
func createPingTask() {
34+
pingTask?.cancel()
35+
pingTask = Task { [weak self] in
36+
while !Task.isCancelled {
37+
guard let self else { return }
38+
do {
39+
try await self.bridge.updateServiceEndpoint(self.xpcListener.endpoint)
40+
try await Task.sleep(nanoseconds: 60_000_000_000)
41+
} catch {
42+
try await Task.sleep(nanoseconds: 1_000_000_000)
43+
Logger.service
44+
.error("Failed to connect to bridge: \(error.localizedDescription)")
45+
}
46+
}
47+
}
48+
}
49+
50+
func connectionDidInvalidate() async {
51+
// ignore
52+
}
53+
54+
func connectionDidInterrupt() async {
55+
createPingTask() // restart the ping task so that it can bring the bridge back immediately.
56+
}
57+
}
58+

0 commit comments

Comments
 (0)