How to get the Settings "window" to PresentUI for captive portals in NEHotspotHelper implementation

Hi,


Recieved the NEHotspotHelper entitlement today and have been experimenting with it for almost 6 hours now. Got most of the parts working including auto-join for psk networks using passwords from the app. However when the network is a captive one, on which window should I present my custom view to interact with the captive portal? I tried it with UIApplication.sharedApplication as AppDelegate and used its window, but the app isn't pushed to the foreground. Is there a window on the Settings app on which I can present my UIVIewController because I've seen an app do this.Here is the snippet of my code.


switch command.commandType {
        case .FilterScanList:

            var networkListCanHandle = [NEHotspotNetwork]()

            guard let networkList = command.networkList else {
                print("No networks in the filter scan list")
                return
            }
        
            for network in networkList {
      
                network.setConfidence(.High)
                networkListCanHandle.append(network)

            }
        
            let response = command.createResponse(.Success)
            response.setNetworkList(networkListCanHandle)
            response.deliver()
        
        case .Evaluate: 
            guard let network = command.network else {
                print("Network not present")
                return
            }
        
            if network.SSID == "My Captive Portal" {
                network.setConfidence(.High)
                let response = command.createResponse(.Success)
                response.setNetwork(network)
                response.deliver()
            }

        case .Authenticate:
          
            guard let network = command.network else {
                print("Network not present")
                return
            }
        
            if network.SSID == "My Captive Portal" {
                network.setConfidence(.High)
                let response = command.createResponse(.UIRequired)
                response.setNetwork(network)
                response.deliver()
            }
        
        
        case .PresentUI:
          
            dispatch_async(dispatch_get_main_queue(), {
                    let customController: UIAlertController = UIAlertController(title: "Captive Login", message: "Let us handle the login", preferredStyle: .Alert)
                   // What should be the window here?? 
                    self.window?.rootViewController?.presentViewController(customController, animated: true, completion: nil)
               })
        
        
        case .Maintain:
             break
        
        case .Logoff:
            break
        
        case .None:
            break
}

Accepted Reply

However when the network is a captive one, on which window should I present my custom view to interact with the captive portal?

The hotspot system will never yank your app to the front; that’s not the way iOS works (-: The standard approach here is to use a local notification to tell the user that you need attention. If they respond to the notification, your app comes to the front and you can present UI in the normal way.

This process is pretty well described in the comments at the top of

<NetworkExtension/NEHotspotHelper.h>
.

In the Authenticating state, if the helper determines that it requires user interaction to proceed, the helper first arranges to alert the user via a UserLocalNotification, then returns a result of UIRequired. The state machine enters the PresentingUI state.

In the PresentingUI state, the helper is given a command of type PresentUI. The application is not kept running in the background in this state: PresentingUI relies on the user bringing the application to the foreground manually or via the UILocalNotification. Once the application has the required information, it returns Success to enter the Authenticated 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/

Replies

However when the network is a captive one, on which window should I present my custom view to interact with the captive portal?

The hotspot system will never yank your app to the front; that’s not the way iOS works (-: The standard approach here is to use a local notification to tell the user that you need attention. If they respond to the notification, your app comes to the front and you can present UI in the normal way.

This process is pretty well described in the comments at the top of

<NetworkExtension/NEHotspotHelper.h>
.

In the Authenticating state, if the helper determines that it requires user interaction to proceed, the helper first arranges to alert the user via a UserLocalNotification, then returns a result of UIRequired. The state machine enters the PresentingUI state.

In the PresentingUI state, the helper is given a command of type PresentUI. The application is not kept running in the background in this state: PresentingUI relies on the user bringing the application to the foreground manually or via the UILocalNotification. Once the application has the required information, it returns Success to enter the Authenticated 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/

So have testing the NEHotspotHelper class now for almost a month and have been facing a couple of problems.

1. The Settings app behaves odly and although my helper app sets password for a WiFi network, the settings app seems to ignore it. This happens only the first time the app is installed, but killing the Settings app and starting it again fixes it. Is there some workaround this?

2. The documentation mentions that the user should have a method to disable the the app NEHotspotHelper functionality. So my question is whether depending on user choice, I should just return network.setConfidence(.None) for all networks in .FilterScanList, if he says 'No' or is there a method to deregister the app as a hotspot helper?


Thanks

Amit

@eskimo
Since local notifications now also require consent from the user, what is the best approach now (seems the documentation about this was never updated since the changes in local notifications in iOS 10).

What if the user decided to not allow notifications (or has not seen the popup to give consent yet)? In this case the captive portal of the hotspot itself will not show (as a helper application is registered), but the user will also not get a notification. Thus meaning the user is in some sort of limbo state then until he or she decides to open our application.

has not seen the popup to give consent yet

I don’t think that’s possible. For you to register your hotspot helper you must have been run by the user, and that’s your opportunity to request notification privileges.

What if the user decided to not allow notifications

This is one of those cases where’s it’s important to tell the user why you’re requesting a privilege and, if they deny it, explain the consequences of that.

Share and Enjoy

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