WiFiFlutter icon indicating copy to clipboard operation
WiFiFlutter copied to clipboard

Method native NEHotspotConfigurationManager.shared.removeConfiguration not working on IOS 15

Open mvn-quannguyen2-dn opened this issue 3 years ago • 23 comments

Hi there,

I am developing an IoT application, your wifi_iot library it helps me a lot in my work, thanks a lot. But now I am facing a problem when using the wifi disconnection function when running the app on IOS 15 device. The specific case is after I connect to wifi using WiFiForIoTPlugin.connect method, then I use WiFiForIoTPlugin.disconnect to disconnect but it doesn't work, although these methods work perfectly when running with IOS 14 and below. I tried to clone the wifi_iot plugin source to install local in the project and debug the plugin's WiFiForIoTPlugin.disconnect method and I see it calls the native removeConfiguration method but nothing happens when calling it. I've tried researching on the internet but haven't seen anyone mention this, maybe iOS 15 is relatively new.

Use wifi_iot 0.3.8 and run it on IOS 15

I look forward to your help, thanks a lot 🙌

mvn-quannguyen2-dn avatar Sep 30 '21 09:09 mvn-quannguyen2-dn

@daadu I look forward to your help, thanks a lot 🙌

mvn-quannguyen2-dn avatar Sep 30 '21 09:09 mvn-quannguyen2-dn

CC: @DominikStarke - because he knows iOS environment better.

daadu avatar Oct 01 '21 06:10 daadu

I just upgraded a phone to iOS 15. Disconnecting from an AP works for me.

A word of warning: If you connect to a known network and disconnect from it, it might happen that the iPhone reconnects to it. You might try the joinOnce flag on connect() and in your phones wifi list ignore your AP.

If this doesn't help please post your entitlements.

DominikStarke avatar Oct 03 '21 08:10 DominikStarke

@DominikStarke cc @daadu I see apple released iOS 15.0.1 in the last week, don't know if you are testing the issue on version IOS 15.0 or 15.0.1, as I mentioned above, my project runs fine with iOS 14 and below.

Here is the config ios to using wifi

image image

App requires location permission before getting wifi information

mvn-quannguyen2-dn avatar Oct 04 '21 04:10 mvn-quannguyen2-dn

@DominikStarke This wifi disconnect function on IOS 15 is not stable, sometimes it can disconnect wifi.

A word of warning: If you connect to a known network and disconnect from it, it might happen that the iPhone reconnects to it. You might try the joinOnce flag on connect() and in your phones wifi list ignore your AP.

This warning I know, so the issue I mentioned above, is not in this case

mvn-quannguyen2-dn avatar Oct 04 '21 09:10 mvn-quannguyen2-dn

There is no other way to disconnect from networks I'm aware of other than NEHotspotConfigurationManager.shared.removeConfiguration

My test yesterday was with iOS 15.0 and I just retested with 15.0.1. Out of ~200 tests disconnect never failed across multiple iPhones (6, 11).

When disconnecting do you see the "trying to disconnect from 'xxx'" (xxx should be the ssid of your ap) log?

If it doesn't show up can you try to replace disconnect with this snippet:

    if #available(iOS 11.0, *) {
        NEHotspotConfigurationManager.shared.getConfiguredSSIDs { (wifiList) in
            wifiList.forEach {
                print("trying to disconnect from'\($0)'")
                NEHotspotConfigurationManager.shared.removeConfiguration(forSSID: $0)
            }
            result(true)
        }
    } else {
        print("Not disconnected")
        result(nil)
    }

Which is a bit more drastic, as it should disconnect even if the ssid doesn't match.

DominikStarke avatar Oct 04 '21 10:10 DominikStarke

@DominikStarke cc @daadu The code you shared above is not working, wifiList.forEach does not return any SSID even though the app is connected to a wifi

When disconnecting do you see the "trying to disconnect from 'xxx'" (xxx should be the SSID of your ap) log?

Yes, when disconnection, I see the log with SSID information, although debug saw the log with SSID information and called the removeConfiguration function, but when running on IOS 15 still can't disconnection, otherwise running on IOS 14 and down, it's normal. My debug picture is below

Screen Shot 2021-10-05 at 6 51 26 PM

mvn-quannguyen2-dn avatar Oct 05 '21 11:10 mvn-quannguyen2-dn

Ok, since getConfiguredSSIDs returns nothing:

getConfiguredSSIDs(completionHandler:) Returns the SSIDs or the names of the Wi-Fi hotspot domains that your app has configured and invokes an optional completion handler.

(see https://developer.apple.com/documentation/networkextension/nehotspotconfigurationmanager/2866695-getconfiguredssids)

This same limitation applies to NEHotspotConfigurationManager.shared.removeConfiguration

Your app can use this method to delete a configuration that it has added, but not a configuration added by another app or by the user.

(see https://developer.apple.com/documentation/networkextension/nehotspotconfigurationmanager/2866727-removeconfiguration)

This means if you connected to the AP manually through the iPhones settings screen or a different app you cannot disconnect from it. In order to verify this go the wifi settings screen and ignore the network, then with your app try to connect & disconnect from the wifi again. This is unfortunately a limitation of iOS, which cannot be lifted.

DominikStarke avatar Oct 05 '21 14:10 DominikStarke

@DominikStarke Sorry, the restriction you mentioned above, I know that restriction. The wifi I want to disconnect on is a wifi connection by the app, not wifi that was manually entered earlier in the settings of the iPhone or another app. It's weird, it works fine on IOS 14 and below, but not on IOS 15. It's strange that the removeConfiguration function works fine on your device

mvn-quannguyen2-dn avatar Oct 05 '21 14:10 mvn-quannguyen2-dn

@DominikStarke I also Forgot WiFi in my iPhone settings and checked it before connecting with the app

mvn-quannguyen2-dn avatar Oct 05 '21 14:10 mvn-quannguyen2-dn

That's weird. Not just my phone. I picked up 6 other iPhones with iOS 15 and 15.0.1 in the office today and none had issues disconnecting.

DominikStarke avatar Oct 05 '21 15:10 DominikStarke

@DominikStarke Thank you very much for supporting me, tomorrow I will try it on many other devices and see how it goes

mvn-quannguyen2-dn avatar Oct 05 '21 15:10 mvn-quannguyen2-dn

I am having the exact same issue. Code worked fine on iphone, ios 14.7. Upgraded that phone to ios 15.0.2. Changed nothing else, it worked on 14.8, failed on 15.0.2. I tried to create a new SSID across both the AP and the iphone (the upgraded phone) to see if somehow that would work. It did not. Deleting/reinstalling app, does not work. Clean build folders ... etc. did not work. Not sure if it matters, but the iot device I am connecting to (ESP32), is not connected to the internet. Happy to help debug this issue (mnv) if you have not found a solution yet.

I did find that all networking activity from the app does stop. It is just the last step of dropping off the hotspot and reconnecting to the prior wifi ap that does not happen.

Seraffimo avatar Oct 20 '21 18:10 Seraffimo

@Seraffimo cc @DominikStarke I still haven't found a solution, the success rate of disconnection is very low on IOS 15, hardly works

mvn-quannguyen2-dn avatar Oct 21 '21 03:10 mvn-quannguyen2-dn

After logging a support ticket with Apple and going through several iterations with their engineers, they confirmed it as a repeatable issue on their side. A feedback request has been logged that will eventually become an official bug. Key to the repeatability was having the joinOnce property set to true - and running on 15.X. Logs of same app running on 14.4 and then 15.10 show that the removeConfiguration(forSSID:) does not trigger the auto-join cycle in IOS 15 for some reason.

Seraffimo avatar Nov 09 '21 20:11 Seraffimo

@Seraffimo Thanks for reporting this with Apple.

Any changes required from our end?

daadu avatar Nov 10 '21 04:11 daadu

@Seraffimo cc @daadu Thank you for reporting the above issue to apple and giving me the above solution, the solution of set joinOnce=false worked, but I check on many devices, wifi disconnect error, sometimes still happens, but the probability of it happening is very low. I just discovered a trick that can temporarily solve this problem until Apple takes care of it, that is when connecting to wifi we will call the connection method twice the first time the app connects, then we have can disconnect normally without any problem.

mvn-quannguyen2-dn avatar Nov 10 '21 15:11 mvn-quannguyen2-dn

@mvn-quannguyen2-dn do you mean the below from plugin readme?

(1) : On iOS, you can only disconnect from a network which has been added by your app. In order to disconnect from a system network, you have to connect to an other!

daadu avatar Nov 10 '21 15:11 daadu

@daadu No, I mean we will call methods connection (WiFiForIoTPlugin.connect) twice repeatedly the first time the app connects to wifi. Of course, disconnect from wifi that is already connected from the app, not the wifi the user connects to in the iPhone settings. It's just a trick to temporarily solve this problem that I'm using

mvn-quannguyen2-dn avatar Nov 10 '21 15:11 mvn-quannguyen2-dn

Ok, just curious how is it solving the problem? I'll have to check the sole thread @Seraffimo mentioned.

@Seraffimo can you post the link to the thread?

daadu avatar Nov 10 '21 15:11 daadu

Hey guys. Thanks for create this library. It works good to Flutter Android.

My situation:

  • iOS 16
  • After connected to the WIFI, disconnect from WIFI failed. Log in XCode console as following:
NEHotspotNetwork nehelper sent invalid result code [1] for Wi-Fi information request
Not connected to a network

JooYoo avatar Sep 27 '23 10:09 JooYoo

The solution for me is the following:

  1. Activate Access Wi-Fi Information capability: AppleDeveloperPortal / Identifiers / [ YOUR APP IDENTIFIER ] / check Access Wi-Fi Information.
  2. Add one more entry in Runner.entitlements as following
<key>com.apple.developer.networking.wifi-info</key>
<true/>
  1. Make sure the app already get the Location permissions.

JooYoo avatar Oct 09 '23 12:10 JooYoo

What I've recently learned is that you can only call .removeConfiguration for wifi networks your app has connected to. You can get a list of which connections iOS thinks your app has connected to by calling .getConfiguredSSIDs (https://developer.apple.com/documentation/networkextension/nehotspotconfigurationmanager/2866695-getconfiguredssids).

In my case, I was connecting to a device that shows a WiFi Captive Portal. During the short time between connecting to the WiFi and the appearance of the Captive Portal, .getConfiguredSSIDs would return the ssid, but once the CaptivePortal appears, for some reason, .getConfiguredSSIDs doesn't return the ssid anymore, showing that iOS no longer thinks your app configured that ssid.

It might have something to do with the lack of internet from the device's wifi, it could be that the Captive Portal is treated in a specific way by iOS that messes with the .getConfiguredSSIDs. Anyhow, it sounds like a bug. We're going to disable the Captive Portal on our side and see if it solves the issue.

silaspedrosa avatar Oct 10 '23 11:10 silaspedrosa