iOS 14 NEHotspotNetwork fetchCurrent method completion block not called

Hi my app us using NEHotspotConfigurationManager
to connect some local network.
I have a logic in the app to check what is SSID of the current connected WiFi network. For this i was using CNCopyCurrentNetworkInfo function. But according to documentation it is deprecated and I should use NEHotspotNetwork.fetchCurrent(completionHandler:).

The thing is that sometimes when i call this method the completion handler is not called so my app wait long time and nothing happens.

Any advice what can be wrong or how to solved this?

using Xcode 12.3, iOS 14.2 and iPhone 11.



Okay, do you have one of the following 4 requirements met:

Code Block text
* @method fetchCurrentWithCompletionHandler:completionHandler:
* @discussion This method returns SSID and BSSID of the current Wi-Fi network when the
* requesting application meets one of following 4 requirements -.
* 1. application is using CoreLocation API and has user's authorization to access precise location.
* 2. application has used NEHotspotConfiguration API to configure the current Wi-Fi network.
* 3. application has active VPN configurations installed.
* 4. application has active NEDNSSettingsManager configuration installed.
* An application will receive nil if it fails to meet any of the above 4 requirements.
* An application will receive nil if does not have the "com.apple.developer.networking.wifi-info" entitlement.


I have a test bed project that uses CoreLocation and the com.apple.developer.networking.wifi-info entitlement and am able to use this API.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Thanks for the reply.

An application will receive nil if it fails to meet any of the above 4 requirements.

But that's not true, in my case. The completion handler is not called.
I just happen randomly and I can't found the cause of this.

even when I use old function CNCopyCurrentNetworkInfo then this method is not finished (i did wait about 30 sec). This is callstack.

Code Block
#0 0x00000001ba7fc2d0 in mach_msg_trap ()
#1 0x00000001ba7fb6d8 in mach_msg ()
#2 0x00000001077b4560 in _dispatch_mach_send_and_wait_for_reply ()
#3 0x00000001077b48fc in dispatch_mach_send_with_result_and_wait_for_reply ()
#4 0x00000001d82a0e68 in xpc_connection_send_message_with_reply_sync ()
#5 0x000000019e8a7984 in NEHelperCopyResponseAndCancel ()
#6 0x000000019e8a9f68 in NEHelperCopyCurrentNetworkInfo ()
#7 0x00000001c579ddf4 in __CNCopyCurrentNetworkInfo ()
#8 0x0000000104fa15c0 in @nonobjc CNCopyCurrentNetworkInfo(_:) ()


Okay, well like I mentioned, I used CoreLocation on a iOS 14.2 project with the following items configured:

Project Entitlements:

Code Block xml
<key>com.apple.developer.networking.wifi-info</key>
<true/>
<key>com.apple.external-accessory.wireless-configuration</key>
<true/>


Project Info.plist:

Code Block xml
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Gather location updates to get SSID</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Gather location updates to get SSID</string>


Code Block swift
import NetworkExtension
import os
import CoreLocation
class ViewController: UIViewController {
var locationManger: CLLocationManager?
override func viewDidLoad() {
super.viewDidLoad()
startLocationManager()
}
func startLocationManager() {
guard locationManger == nil else {
locationManger?.requestWhenInUseAuthorization()
locationManger?.startUpdatingLocation()
return
}
locationManger = CLLocationManager()
locationManger?.delegate = self
locationManger?.desiredAccuracy = kCLLocationAccuracyKilometer
locationManger?.requestWhenInUseAuthorization()
locationManger?.startUpdatingLocation()
}
@IBAction func testNetwork() {
NEHotspotNetwork.fetchCurrent(completionHandler: { (network) in
if let unwrappedNetwork = network {
let networkSSID = unwrappedNetwork.ssid
os_log("Network: %{public}@ and signal strength %d", networkSSID , unwrappedNetwork.signalStrength)
} else {
os_log("No available network")
}
})
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let lastLocation = locations.last {
...
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
/* Detect the CLAuthorizationStatus and enable the capture of associated SSID. */
if status == CLAuthorizationStatus.authorizedAlways ||
status == CLAuthorizationStatus.authorizedWhenInUse {
...
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
if let error = error as? CLError, error.code == .denied {
...
manager.stopUpdatingLocation()
}
}
}


Notice that this example uses CoreLocation, but as the description mentions, NEDNSSettingsManager or NETunnelProviderManager could be used too.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Has anyone tested NEHotspotNetwork.fetchCurrent on iOS 15?

I have a project (with NETunnelProviderManager) which when i run on iOS 14.6 device everything works as expected. When i run the same project on iOS 15 Beta 3 device, the NEHotspotNetwork.fetchCurrent callback always return a nil object.

When i run the same project on iOS 15 Beta 3 device, the NEHotspotNetwork.fetchCurrent callback always return a nil object.

You should definitely file a bug about that.

Please post your bug number, just for the record.

Share and Enjoy

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

Thanks for the quick response!

Bug report is submitted. ID: FB9361196

When i run the same project on iOS 15 Beta 3 device, the NEHotspotNetwork.fetchCurrent callback always return a nil object.

The issue is still present on my end on iOS 15 Beta 8.

I don't really want to burn a TSI on this.

I agree that a TSI won’t help here. Based on my reading of juraj_ivpn’s bug report (FB9361196) it’s clear that this is Just a Bug™. Apple Engineering sets their own priorities when it comes to bug fixes, and a DTS TSI can’t help with that.

Just hoping this gets resolved before GM

Unfortunately I can’t make any promises on that front.

Share and Enjoy

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

The issue is still not fixed on iOS 15 GM.

The issue is still not fixed on iOS 15 GM.

Indeed. You will have to find a way to live with this bug on the released version of iOS 15.0 )-:

Beyond that, I recommend that you continue to test with iOS beta releases as they get seeded.

Share and Enjoy

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

I can confirm that the issue is fixed on iOS 15.1 RC / public release.

NEHotspotNetwork.fetchCurrent is now working as expected.

I have confirmed that a similar bug can be reproduced on iPad OS 15.1.
The method is to turn off the iPad for half a day and then connect to the device via Wifi again.
Null will be returned after 20 seconds. After another 4 seconds, the SSID will be returned again.
This only happens once after the iPad is turned on.

iOS 14 NEHotspotNetwork fetchCurrent method completion block not called
 
 
Q