This is a typical infrastructure Wi-Fi network, right? So not peer-to-peer Wi-Fi? And it has access to the wider Internet?
I just cooked up a trivial test app to exercise this and it’s working for me. The code is below if you’re interested (sorry it’s so ugly).
In the code snippet in your original post you configure parameters
really strangely. If you do what I did, just use .tcp
, does that improve things?
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
import UIKit
import Network
final class MainViewController: UITableViewController {
struct Service {
var name: String
var endpoint: NWEndpoint
var interface: NWInterface?
var connection: NWConnection?
}
let browser: NWBrowser = .init(for: .bonjour(type: "_ssh._tcp.", domain: "local."), using: .tcp)
override func viewDidLoad() {
super.viewDidLoad()
self.browser.stateUpdateHandler = { state in
print(state)
}
self.browser.browseResultsChangedHandler = { services, _ in
self.services = services.map { result in
guard case .service(name: let name, type: _, domain: _, interface: let interface) = result.endpoint else { fatalError() }
return Service(name: name, endpoint: result.endpoint, interface: interface, connection: nil)
}
self.tableView.reloadData()
}
self.browser.start(queue: .main)
}
var services: [Service] = []
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
services.count
}
func sync(cell: UITableViewCell, at indexPath: IndexPath) {
let service = services[indexPath.row]
cell.textLabel!.text = "\(service.name) [\(service.interface?.name ?? "-")]"
let status: String
switch service.connection?.state {
case nil: status = "-"
case .setup?: status = "setup"
case .waiting(_)?: status = "waiting"
case .preparing?: status = "preparing"
case .ready?: status = "ready"
case .failed(_)?: status = "failed"
case .cancelled?: status = "cancelled"
@unknown default: status = "?"
}
cell.detailTextLabel!.text = status
}
func syncCell(at indexPath: IndexPath) {
guard let cell = self.tableView.cellForRow(at: indexPath) else { return }
self.sync(cell: cell, at: indexPath)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
self.sync(cell: cell, at: indexPath)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let connection = self.services[indexPath.row].connection {
self.services[indexPath.row].connection = nil
connection.cancel()
} else {
let endpoint = self.services[indexPath.row].endpoint
let connection = NWConnection(to: endpoint, using: .tcp)
self.services[indexPath.row].connection = connection
connection.stateUpdateHandler = { newState in
self.syncCell(at: indexPath)
}
connection.start(queue: .main)
}
self.syncCell(at: indexPath)
tableView.deselectRow(at: indexPath, animated: true)
}
}