XCTest Bundle cannot access local network using NWConnect

I am working on a XCTest UI test automation and I want to add the ability to communicate with a test hub on our local network that controls external test equipment that is being used to create test conditions that are external to the IPAD. Currently when I run the test on the simulator running on a MAC mini it works fine and communicates with the external machine but if I run on target which is a 6th Get IPAD it receives "POSIXErrorCode(rawValue: 50): Network is down" I have tried to add permissions to the test bundle to allow this to work but nothing seems to fix it. I am a novice when it comes to IOS development in general so maybe I am missing something obvious. I thought that this https://developer.apple.com/forums/thread/668729 solution would fix my problem but adding the permissions didn't help. I am using Xcode 13.4.1, the IOS on the target is version 15.5.

Replies

This is fallout from local network privacy. Before going further, read Local Network Privacy FAQ.

when I run the test on the simulator running on a MAC mini it works

Local network privacy is an iOS feature [1]. The simulator uses the macOS networking stack, which is why things work there.

When you run a unit test on an iOS device it’s hosted in one of two processes:

  • Your app

  • An Xcode unit test runner

Which one you get depends on the Host Application popup in the Testing slide of the General tab of the test’s target editor. If that’s None, you get the Xcode unit test runner.

The Xcode unit test runner is not authorised to use the local network and there’s no reasonable way to get it authorised. To make this work, you’ll need to host the unit test in your app. At that point you can authorise the app like you would any other.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] For iOS, read iOS and iPadOS.

Right, just to add on to the key point that Quinn is bringing up here:

The Xcode unit test runner is not authorised to use the local network and there’s no reasonable way to get it authorised. To make this work, you’ll need to host the unit test in your app. At that point you can authorise the app like you would any other.

Notice in that thread that you are referencing that I am invoking the local network access in the app and the XCUIApplication invocation is merely triggering the button in the app that make the local network call in the app, not the test runner.

I looked at the General Tab of the test's target and it is set to the app currently, however the app doesn't currently use the local network at all. I did create a standalone app to test the concept and it works as expected on the target iPad. The prototype code is based on an example that you had posted that uses NWConnect. I compare the two projects and I don't see anything obvious as to why the app that I am testing can not access the local network. Is there specific privileges that I need to check to tell why the app I am testing cannot access the network. Thanks for your help, Don

Is there specific privileges that I need to check to tell why the app I am testing cannot access the network.

Yes, but it’s a privilege granted by the user. If you delete the app from the test device and then retest, you should see the local network privacy prompt.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I was out of the office for a couple of days last week, so I tried this today. I removed the main app and the V&V app from the target IPAD and then from Xcode ran the test that accesses the TCPIP connection. I didn't get the prompt for the local network, I did get prompts for using Bluetooth and the camera which the app does use. I didn't see any messages on my TCPIP server on the network. It failed the same as before with the POSIX 50 message as shown above, so I am kind of stuck at this point. I will try my stand alone app tomorrow and see if there is anything that is different when I delete it from the IPAD and execute it from Xcode.

I checked that the stand alone app works as expected and I also noticed that while the app is waiting for the prompt it logs the POSIX 50 error just as the test case does when it runs, but in the test case, the prompt doesn't appear. Is it possible the app I am testing has some other setting that would prevent the prompt from appearing? I don't see anything obvious.

Is it possible the app I am testing has some other setting that would prevent the prompt from appearing?

I suspect that this is more to do with the way that the test environment runs your app.

If you run the app normally, trigger the prompt, allow local network access, and then run the app under test, does the test get access to the local network?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I have been experimenting. Currently the app that I am testing doesn't use the local network. So { added access to the local network into the app and I did receive the prompt and was able to access the network. I then ran the test version and even though the main app had permission to use the local network, the test couldn't get to it. Then while the test was running and unable send over the local network, I manually, triggered the screen that I had the local network access, it did communicate. Any ideas? This prompted me to ask another question, Is there a way to use the host computer that is running Xcode to send data over the local network? I see the loging being displayed in the Xcode IDE while my test is running is there anyway to add other control task, while a test is running. I could see where this might be another approach to the problem, the control of external HW isn't required to run on target, just need to synchronize it with the UI control of the system.

Currently the app that I am testing doesn't use the local network.

Ah, yeah, that makes sense given your initial description of your setup.

Is there a way to use the host computer that is running Xcode to send data over the local network?

Sure. Local network privacy doesn’t apply to the Mac. However, I don’t see how that helps you. I guess the test bundle running inside your app could start a listener [1] but there’s no easy way for the Mac to discover that.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Which doesn’t require local network privacy, per FAQ-2 in the Local Network Privacy FAQ.

I think the way that I asked the question was confusing. It comes down to what is actually running on the host Mac when Xcode is executing a test, is there a way to run code on the host Mac as part of executing the test on the target device. Right now if I call NSLog the output is shown on a window on the Mac in Xcode. If you could Send NSLog data to a TCP/IP port I could make that work for what I am trying to accomplish. When I first was doing this I thought that most of the XCTest was running on the host and the screen drive elements were on the iPad and they were controlled thought the USB. After working with it for a while I realize that most/all of it is running on the Target, but is it possible to do anything on the host.

> is there a way to run code on the host Mac as part of executing the test on the target device.

Not really. You could try bodgying something together with a Test pre-action script but I suspect that’d end up being very brittle.

> If you could Send NSLog data to a TCP/IP port I could make that work for what I am trying to accomplish.

The Mac has access to log entries coming off the device but, sadly, the OSLog framework does not support real-time access to device logs. You can see them by the log command but… sheesh… that’d be adding a bodge on top of a bodge.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Ok I am running out of options, so let me ask a couple of questions. Should using TCP network connection over the local network be possible from the UI test bundle. Your initial response indicated that it should be, even though I haven’t been able to get it to work. In the original thread I reference, the person asking the question was trying to accomplish a very similar task and at that time he was told to open a bug report. Has that bug been fixed and is it working with IOS 15.5. I have included the thread and bug number here as well. https://developer.apple.com/forums/thread/668729

FB8983382

OK, so I’ve definitely misread the top of this thread because I thought the focus here was unit tests, not UI tests. Sorry about that.

I’m much less confident about my understanding of UI tests. Given that, my advice is for you to open a DTS tech support incident so that I can allocate the time to investigate this properly.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I opened a DTS tech support incident, the reference number is Case-ID: 1859992. Thanks, Don

  • Ta! This has landed in my queue and I'll get back to you on Monday.

Add a Comment

English: I also encountered such a problem, there is a solution is not to use WIFI, but use Mac to share the network, through USB sharing to provide the mobile phone network, but this is just a curved solution, wifi is always unable to access the local network, this should be the iOS system bug. If runner can access the local network using wifi, please tell me the correct solution, at least for now, I haven't seen a real solution yet.

中文: 我也遇到了这样的问题,有个解决办法就是不使用WIFI,而使用Mac共享网络,通过USB共享给手机提供网络,但是这只是一个曲线解决办法,wifi始终都是没法访问到本地网络的,这应该是ios的系统bug. 如果runner使用wifi的情况能访问本地网络,请告诉我正确的解决方案,至少目前,我暂时还没看到真正的解决办法.

  • How are you able to share a USB connection while running on target. I am running on an IPAD which has a USB-C connector will this work with a hub? I thought that there would be a problem with that setup. Is there an adapter that solves this problem?

Add a Comment