4

We tried out the new NetworkExtension API. We were successful in recreating all the steps in our app. But, we have an issue that we are still not seeing the custom annotation below the SSID name in the Wifi settings screen. We are on ios 9 Beta 3, xcode 7 beta 3.

We have done these steps successfully:

  • @note 1 The application's Info.plist MUST include a UIBackgroundModes array  *   containing 'network-authentication'.

  • @note 2  *   The application MUST set 'com.apple.developer.networking.HotspotHelper'  *   as one of its entitlements. The value of the entitlement is a boolean  *   value true.

Here's our code in the App. We are trying to annotate a SSID by the name of "Internet" by a text "Try Here". We get the log that the setConfidence method is called for SSID "Internet". Yet, we do not see the actual annotation in the Wifi selection screen.

We also tried to pass 'nil' for the options object which promised to show the App name as the default annotation. But we do not see that either. We get return 'true' for the call to method registerWithOptions() and we do get callbacks when we open the wifi settings screen

 

NSMutableDictionary* options = [[NSMutableDictionary alloc] init]; 
[options setObject:@"Try Here" forKey:kNEHotspotHelperOptionDisplayName]; 
 dispatch_queue_t queue = dispatch_queue_create("com.myapp.ex", 0); 
BOOL returnType = [NEHotspotHelper registerWithOptions:options queue:queue 
handler: ^(NEHotspotHelperCommand * cmd) { 
    if(cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList ) { 
         
        for (NEHotspotNetwork* network  in cmd.networkList) {  
            if ([network.SSID isEqualToString:@"Internet"]){ 
                [network setConfidence:kNEHotspotHelperConfidenceHigh];               
                NSLog(@"Confidance set to high for ssid:%@",network.SSID); 
            }  
        }    
    } 
}];

=========================

Please help us to understand what we are missing ?

Senseful
  • 86,719
  • 67
  • 308
  • 465
santosh
  • 504
  • 2
  • 6
  • 20

3 Answers3

7

I have implemented the below code for authenticating and annotating the Wifi hotspot with "Connect to MyWifi" for SSID "TP-LINK" from within the app, It works fine.

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@"Connect to MyWifi", kNEHotspotHelperOptionDisplayName, nil];

dispatch_queue_t queue = dispatch_queue_create("com.myapp.ex", 0);
BOOL isAvailable = [NEHotspotHelper registerWithOptions:options queue:queue handler: ^(NEHotspotHelperCommand * cmd) {
    NSMutableArray *hotspotList = [NSMutableArray new];

    if(cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList) {
        for (NEHotspotNetwork* network  in cmd.networkList) {
            NSLog(@"network name:%@", network.SSID);
            if ([network.SSID isEqualToString:@"TP-LINK"]) {
                [network setConfidence:kNEHotspotHelperConfidenceHigh];
                [network setPassword:@"<wifi-password>"];                    
                [hotspotList addObject:network];
            }
        }

        NEHotspotHelperResponse *response = [cmd createResponse:kNEHotspotHelperResultSuccess];
        [response setNetworkList:hotspotList];
        [response deliver];
    }
}];

Note: For the above code to work,

  1. you need to get entitlement access from apple by mailing them on networkextension@apple.com.
  2. Once you have the entitlement, you need to create new provisioning profile where you will have to add the network extension entitlement(available only if you have access) and use that profile in your xcode for it to work.
  3. Add entitlement com.apple.developer.networking.HotspotHelper to true in your entitlement file in your xcode enter image description here
  4. In Info.plist add network-authentication key to Required background modes array enter image description here Hope that helps. Thanks
sahiljain
  • 2,215
  • 1
  • 29
  • 39
  • I got a true flag for "isAvailable" BOOL, but it does not execute my block items. – g212gs Dec 13 '16 at 05:02
  • 2
    How did check if it's not going into your block? Did you go to iOS Wifi settings and wait for scanning of wifi list? block is called during scanning of wifi list in wifi settings – sahiljain Dec 14 '16 at 05:59
  • Also reading this will give you a better understanding about the HotspotHelper https://github.com/theos/sdks/blob/master/iPhoneOS9.3.sdk/System/Library/Frameworks/NetworkExtension.framework/Headers/NEHotspotHelper.h – Pierre Feb 23 '17 at 09:48
  • For a Swift version of this code, see my example in [this answer](https://stackoverflow.com/a/52472782/35690). – Senseful Sep 24 '18 at 04:40
1

You first need to register your app as Hotspot Helper via email https://forums.developer.apple.com/thread/11807

littlecode
  • 11
  • 2
1

It seem it does not work exactly that way. A NEHotspotHelperCommand object actually expects a NEHotspotHelperResponse. You cannot modify the networks directly.

All your are missing in your code is the delivery of the NEHotspotHelperResponse.

NSMutableDictionary* options = [[NSMutableDictionary alloc] init];
[options setObject:@"Try Here" forKey:kNEHotspotHelperOptionDisplayName];
dispatch_queue_t queue = dispatch_queue_create("com.myapp.ex", 0);
BOOL returnType = [NEHotspotHelper registerWithOptions:options queue:queue handler: ^(NEHotspotHelperCommand * cmd) {
   if (cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList ) {
       for (NEHotspotNetwork* network  in cmd.networkList) {
           if ([network.SSID isEqualToString:@"Internet"]) {
               [network setConfidence:kNEHotspotHelperConfidenceHigh];

               // This is required
               NEHotspotHelperResponse *response = [cmd createResponse:kNEHotspotHelperResultSuccess];
               [response setNetworkList:@[ network ]];
               [response deliver];   

               NSLog(@"Confidance set to high for ssid:%@",network.SSID); 
           }  
       }    
   } 
}];

Hope that helps. It's been over a month, but I just got cleared for this entitlement.

teos
  • 109
  • 1
  • 6
  • It didn't work for me calling `setNetwork:`, I had to add the networks in an array and then call `setNetworks:` – Pablo A. Sep 16 '15 at 16:45
  • You are correct, I edited the code. For more details: kNEHotspotHelperCommandType.FilterScanList and .Evaluate commands are associted with a list of networks, while others (ex: .Authenticate) are associated with one network only. We need to respond with setNetwork: or setNetworkList: accordingly, – teos Sep 16 '15 at 23:01
  • I never get cmd.commandType == kNEHotspotHelperCommandTypeAuthenticate get called. Is there any specific reason ? It only calls kNEHotspotHelperCommandTypeEvaluate and kNEHotspotHelperCommandTypeFilterScanList all the time. – TechFlitter Sep 23 '15 at 15:12
  • @TechFlitter, have you managed to get cmd.commandType == kNEHotspotHelperCommandTypeAuthenticate get called ? I have the same issue now. Maybe we can collaborate on finally get this work – Roma Oct 06 '15 at 14:24