Skip to content

Commit 3ce7f81

Browse files
committed
LocalNetworkAuthorization: Rework for more reliabilty.
As it turns out, the _remotepairing._tcp service is not always online, so we better register our own service to make sure the NWBrowser can actually find something.
1 parent b1b093d commit 3ce7f81

File tree

1 file changed

+21
-2
lines changed
  • Sources/CornucopiaCore/DeviceFeatureAuthorization

1 file changed

+21
-2
lines changed

Sources/CornucopiaCore/DeviceFeatureAuthorization/LNA.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ private let logger = Cornucopia.Core.Logger()
1111
public final class LocalNetworkAuthorization: NSObject {
1212

1313
@frozen public enum State {
14-
1514
case notDetermined
1615
case denied
1716
case granted
@@ -29,7 +28,16 @@ public final class LocalNetworkAuthorization: NSObject {
2928
self.shutdown()
3029
}
3130
}
31+
32+
private let serviceType: String = {
33+
let firstRegisteredBonjourServiceType = Bundle.main.CC_nsBonjourServices.first ?? "unknown"
34+
precondition(firstRegisteredBonjourServiceType != "unknown", "No bonjour service registered in plist. Add the key `NSBonjourServices` to your app's Info.plist file and register a service, e.g. `_lna_check._tcp`.")
35+
logger.trace("LNA service type is \(firstRegisteredBonjourServiceType)")
36+
return firstRegisteredBonjourServiceType
37+
}()
38+
3239
private var browser: NWBrowser? = nil
40+
private var listener: NWListener? = nil
3341
private var continuation: CheckedContinuation<State, Never>? = nil {
3442
didSet {
3543
if self.continuation != nil {
@@ -38,10 +46,17 @@ public final class LocalNetworkAuthorization: NSObject {
3846
}
3947
}
4048

49+
private func createListener() -> NWListener {
50+
let listener = try! NWListener(using: NWParameters(tls: .none, tcp: NWProtocolTCP.Options()))
51+
listener.service = NWListener.Service(name: UUID().uuidString, type: self.serviceType)
52+
listener.newConnectionHandler = { _ in } // Must be set or else the listener will error with POSIX error 22
53+
return listener
54+
}
55+
4156
private func createBrowser() -> NWBrowser {
4257
let parameters = NWParameters()
4358
parameters.includePeerToPeer = true
44-
let browser = NWBrowser(for: .bonjour(type: "_remotepairing._tcp", domain: nil), using: parameters)
59+
let browser = NWBrowser(for: .bonjour(type: self.serviceType, domain: nil), using: parameters)
4560
browser.stateUpdateHandler = { [weak self] state in
4661
logger.trace("LNA browser status update: \(state)")
4762
guard let self else { return }
@@ -61,13 +76,17 @@ public final class LocalNetworkAuthorization: NSObject {
6176
}
6277

6378
private func startBrowsing() {
79+
self.listener = self.createListener()
80+
self.listener?.start(queue: .main)
6481
self.browser = self.createBrowser()
6582
self.browser?.start(queue: .main)
6683
}
6784

6885
private func shutdown() {
6986
self.browser?.cancel()
7087
self.browser = nil
88+
self.listener?.cancel()
89+
self.listener = nil
7190
self.continuation = nil
7291
}
7392

0 commit comments

Comments
 (0)