The solution I've found in the Xcode 15.3 working with iOS 17.4.1 made me SICK! I couldn't find any doc about it, but I'm sure it works. You have to bring your xctrunner app to front, this way OS asks for local network permission in UI test target.
Try this in your UI test target without need to specify NSLocalNetworkUsageDescription and bonjour services, etc.
func testXCTRunnerToAskForLocalNetworkPermission() {
// without bringing xctrunner to front, permission alert won't be shown.
let app = XCUIApplication(bundleIdentifier: "{YOUR_APP_BUNDLE_ID}UITests.xctrunner")
app.activate()
connectToLocalNetwork()
waitFor(aSecond: 1)
let springBoard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
// Allows local network permission.
let button = springBoard.alerts.firstMatch.buttons["Allow"]
if button.exists {
button.tap()
// local network is allowed in current running ui test.
connectToLocalNetwork() // try to connect, as it's allowed now.
}
// Keep XCUITest running forever, though sometimes it stops automatically
wait(for: [expectation(description: "keep running")], timeout: .infinity)
}
waiter helper function:
func waitFor(aSecond seconds: TimeInterval) {
let expectation = expectation(description: "waiting for \(seconds)")
let timer = Timer(timeInterval: seconds, repeats: false) { _ in
expectation.fulfill()
}
wait(for: [expectation], timeout: seconds)
}
local network function:
func connectToLocalNetwork() {
URLSession.shared.dataTask(with: URLRequest(url: URL(string: "http://192.168.2.101:5055")!)) { data, response, error in
if let data {
print("Data: \(String(data: data, encoding: .utf8) ?? "")")
}
}.resume()
}