WebClient works until WiFi SSID changed

DooksDooks ZAMember ✭✭✭

Good day,

I am doing a request to a server using the following code:

try
{
    using (var client = new WebClient())
    {
        var parameters = "?param1=data";
        string json = client.UploadString(MyConfigurations.MyURL + parameters, ""); //breaks here
    }
}
catch (Exception ex)
{
      /*
       *  Exception:
       *  -----------

       System.Net.WebException: Error: ConnectFailure (System call failed) ---> System.Net.Sockets.SocketException: System call failed
       at System.Net.Sockets.Socket..ctor (System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) [0x00057] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/System/System.Net.Sockets/Socket.cs:181 
       at System.Net.WebConnection.Connect (System.Net.HttpWebRequest request) [0x000cf] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/System/System.Net/WebConnection.cs:171 
       --- End of inner exception stack trace ---
       at System.Net.WebClient.UploadDataInternal (System.Uri address, System.String method, System.Byte[] data, System.Net.WebRequest& request) [0x000a6] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/System/net/System/Net/webclient.cs:587 
       at System.Net.WebClient.UploadString (System.Uri address, System.String method, System.String data) [0x00054] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/System/net/System/Net/webclient.cs:868 
       at System.Net.WebClient.UploadString (System.String address, System.String data) [0x00011] in /Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/System/net/System/Net/webclient.cs:839 
       at (wrapper remoting-invoke-with-check) System.Net.WebClient:UploadString (string,string)
      */
}

It only breaks when I switch to another SSID on the WiFi and wont work until I close and open the app again.

Answers

  • njakubowicznjakubowicz Member ✭✭

    Is the above code getting called multiple times, from elsewhere?
    Also did your resolve your issue, as I am trying to debug a similar issue. But have not pinpointed any culprits in code yet.

  • DooksDooks ZAMember ✭✭✭

    No the problem was that, you need to ALWAYS respond after iOS handed your app control of the WiFi for the moment.

    This is was my code (dumbed down, removed all the checks if it is my wifi hotspot etc. but the following code should work perfectly):

        public Init()
        {
            NEHotspotHelperOptions options = new NEHotspotHelperOptions(NSDictionary.FromObjectAndKey(new NSString("My Wifi Avalable Here"), NEHotspotHelperOptionInternal.DisplayName));
            bool isAvailable = Register(options, DispatchQueue.MainQueue, HotspotHandler);
        }
    
        private void HotspotHandler(NEHotspotHelperCommand cmd)
        {
            NEHotspotHelperResponse response;
    
            try
            {
                var ScanResults = (cmd.NetworkList ?? new NEHotspotNetwork[0]).ToList();
                var ConnectedNetwork = SupportedNetworkInterfaces?.Last();
    
                switch (cmd.CommandType)
                {
                    case NEHotspotHelperCommandType.FilterScanList: // Set confidence on all hotspots is "My Wifi"
                        {
                            response = cmd.CreateResponse(NEHotspotHelperResult.Success);
    
                            var newList = ScanResults.Where(n => MyWiFiSSID == n.Ssid).ToList();
                            newList.ForEach(n => n.SetConfidence(NEHotspotHelperConfidence.High));
    
                            response.SetNetworkList(newList.ToArray());
    
                            response.Deliver();
    
                            break;
                        }
                    case NEHotspotHelperCommandType.Evaluate: // First Step "Evaluate" after a user connected to My Wifi Hotspot
                    case NEHotspotHelperCommandType.PresentUI:
                        {
                            ConnectedNetwork.SetConfidence(NEHotspotHelperConfidence.High);
    
                            response = cmd.CreateResponse(NEHotspotHelperResult.Success);
                            response.SetNetwork(ConnectedNetwork);
    
                            response.Deliver();
    
                            break;
                        }
                    case NEHotspotHelperCommandType.Authenticate: // Second Step "Authenticate" after Evaluate is done.
                    case NEHotspotHelperCommandType.Maintain: // Third Step "Maintain" - random step
                        {
                            ConnectedNetwork.SetConfidence(NEHotspotHelperConfidence.High);
    
                            response = cmd.CreateResponse(NEHotspotHelperResult.Success);
                            response.SetNetwork(ConnectedNetwork);
    
                            Authenticate(); // Do your network calls here -> Synchronously
    
                            response.Deliver();
    
                            break;
                        }
                    case NEHotspotHelperCommandType.Logoff:
                    case NEHotspotHelperCommandType.None:
                    default:
                        {
                            response = cmd.CreateResponse(NEHotspotHelperResult.Success);
                            response.Deliver();
                            break;
                        }
                }
            }
            catch (Exception ex)
            {
                response = cmd.CreateResponse(NEHotspotHelperResult.UnsupportedNetwork); // Error
                response.Deliver();
            }
        }
    

    For the Init() code to work, you need to have the following in your entitlements.plist file as well as tick it when provisioning in the apple dev console:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>com.apple.developer.networking.HotspotHelper</key>
        <true/>
    </dict>
    </plist>
    

    Then only will your app be able to register the handler in init()

Sign In or Register to comment.