Show captive portal UI and hotspot helper authenticate command

I am using the hotspot helper to provide passwords to some secure networks. For this purpose, everything works fine, but I also want to present the captive portal in open networks with it.


Looking at this guide(see part "Sequence when network is captive and UI is required"), I understand that, when receiving Authenticate command I should be able to determine whether the network is captive or not(*), and based on that I should return success or UIRequired response. The problem is that I don't have network access at this point(I get -1009 error code from my request). I only get it after delivering the response. As stated in the link above, in case of captive portal(I need network access to determine it, and don't have it before delivering the response to the .Authenticate command) I should post a local notification, return UIRequired to the hotspot helper, and once the captive webpage is presented return success to the PresentUI command I would get.


Am I doing anything wrong? Is presenting the captive webpage not possible / recommended on iOS?



* I am doing this with a request to a known endpoint and checking if the response is the expected one or not; if it is, there is no captive portal, if it is not, there is. Is this the recommended way?

The problem is that I don't have network access at this point …

You should have network access when you get the

.Authenticate
command. One gotcha is that Wi-Fi isn’t the default route at this point (the reasons for which are kinda obvious when you think about it), so you have to force your network connections to run over the Wi-Fi. You do this as follows:
  • for HTTP, call

    -[NSMutableURLRequest bindToHotspotHelperCommand:]
  • for TCP, create the connecting using

    -[NEHotspotHelperCommand createTCPConnection:]
  • for UDP, create the session using

    -[NEHotspotHelperCommand createUDPSession:]

ps If you haven’t already read my NEHotspotHelper pseudo API post, please do. It can help clarify stuff like this.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

WWDC runs Mon, 13 Jun through to Fri, 17 Jun. During that time all of DTS will be at the conference, helping folks out face-to-face. http://developer.apple.com/wwdc/

Thank you very much for your response.

Was not aware about the default route, but as you say is obvious.

I have another question: when receiving authenticate command, right after I deliver my response with .Success, is the default route the network I am authenticating? Will a network request executed right after delivering the response be routed over this network(without binding it to the hotspot helper command)?

I have another question: when receiving authenticate command, right after I deliver my response with .Success, is the default route the network I am authenticating?

It depends on what you mean by “right after”. The

deliver
method is asynchronous. It tells the hotspot machinery to start moving to the next state but there’s no guarantee that this state change has happened at the time that
-deliver
returns. Thus, there’s a race between any code you run after
-deliver
returns and the default route changing.

If you want requests to go over the Wi-Fi, I recommend you bind them to the Wi-Fi regardless of the state.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

WWDC runs Mon, 13 Jun through to Fri, 17 Jun. During that time all of DTS will be at the conference, helping folks out face-to-face. http://developer.apple.com/wwdc/

Hi Eskimo,

i'm testing the method:


[NSMutableURLRequest bindToHotspotHelperCommand:]


I have this NSMutableURLRequest


//hcom is a NEHotspotHelperCommand
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request bindToHotspotHelperCommand:hcom];


If I use the NSMutableURLRequestit in a NSURLSessionDataTask It works like a charme.


But when I try to load the same NSMutableURLRequest in a UIWebView using


[self.webView loadRequest:request];


I receive the error


Error Domain=kCFErrorDomainCFNetwork Code=-1009 "The Internet connection appears to be offline."


so it seems that the NSMutableURLRequest with bindToHotspotHelperCommand is not applicable to UIWebView, have you any evidences of it?

so it seems that the NSMutableURLRequest with bindToHotspotHelperCommand is not applicable to UIWebView, have you any evidences of it?

I vaguely remember another developer tripping across this. It’s not a huge surprise: UIWebView ends up issuing a bunch of requests internally and it does not guarantee to propagate properties to those requests from the original request you passed in to kick everything off.

Have you tried WKWebView? I expect it will have the same problem but, once you’ve confirmed the problem there, you can file a bug requesting that it do the right thing (or provide an explicit API for binding to an interface). Please post your bug number, just for the record.

You might be able to work around this by going back to UIWebView and using a custom NURLProtocol to re-issue its requests with the interface bound properly. See the CustomHTTPProtocol sample code for the details.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Bug #31063939

Show captive portal UI and hotspot helper authenticate command
 
 
Q