diff --git a/src/ios/WifiWizard2.m b/src/ios/WifiWizard2.m index 675c571..1eee4dd 100644 --- a/src/ios/WifiWizard2.m +++ b/src/ios/WifiWizard2.m @@ -2,21 +2,32 @@ #include #import #import -#import +#import @implementation WifiWizard2 - (id)fetchSSIDInfo { - // see http://stackoverflow.com/a/5198968/907720 - NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces(); - NSLog(@"Supported interfaces: %@", ifs); - NSDictionary *info; - for (NSString *ifnam in ifs) { - info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam); - NSLog(@"%@ => %@", ifnam, info); - if (info && [info count]) { break; } + // For iOS 14+, use NEHotspotNetwork.fetchCurrent instead of deprecated CNCopyCurrentNetworkInfo + NSLog(@"[WifiWizard2] fetchSSIDInfo called"); + + if (@available(iOS 14.0, *)) { + NSLog(@"[WifiWizard2] iOS 14+ detected - returning nil to avoid deprecated API"); + // NEHotspotNetwork.fetchCurrent is the modern API but requires entitlements and location permission + // Return nil to indicate we should not rely on this for verification on iOS 14+ + return nil; + } else { + NSLog(@"[WifiWizard2] iOS 11-13 detected - using legacy CNCopyCurrentNetworkInfo"); + // iOS 11-13: Still use the old method + NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces(); + NSLog(@"Supported interfaces: %@", ifs); + NSDictionary *info; + for (NSString *ifnam in ifs) { + info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam); + NSLog(@"%@ => %@", ifnam, info); + if (info && [info count]) { break; } + } + return info; } - return info; } - (BOOL) isWiFiEnabled { @@ -38,7 +49,7 @@ - (BOOL) isWiFiEnabled { } - (void)iOSConnectNetwork:(CDVInvokedUrlCommand*)command { - + __block CDVPluginResult *pluginResult = nil; NSString * ssidString; @@ -51,26 +62,55 @@ - (void)iOSConnectNetwork:(CDVInvokedUrlCommand*)command { if (@available(iOS 11.0, *)) { if (ssidString && [ssidString length]) { + NSLog(@"[WifiWizard2] iOSConnectNetwork - Attempting to connect to SSID: %@", ssidString); + NEHotspotConfiguration *configuration = [[NEHotspotConfiguration - alloc] initWithSSID:ssidString - passphrase:passwordString + alloc] initWithSSID:ssidString + passphrase:passwordString isWEP:(BOOL)false]; configuration.joinOnce = false; - + [[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:^(NSError * _Nullable error) { - - NSDictionary *r = [self fetchSSIDInfo]; - - NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; //@"SSID" - - if ([ssid isEqualToString:ssidString]){ - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; - }else{ + + if (error) { + // Check if error code is 13 (NEHotspotConfigurationErrorAlreadyAssociated) + // This means we're already connected to this network - treat as success + if (error.code == 13) { + NSLog(@"[WifiWizard2] iOSConnectNetwork - Already connected to SSID: %@", ssidString); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + // Connection failed with other error + NSLog(@"[WifiWizard2] iOSConnectNetwork - Connection FAILED with error: %@", error.description); pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + + // iOS 14+: Trust NEHotspotConfigurationManager result + // CNCopyCurrentNetworkInfo is deprecated and unreliable, requires location permission + if (@available(iOS 14.0, *)) { + // On iOS 14+, if no error was returned, connection is successful + NSLog(@"[WifiWizard2] iOSConnectNetwork - iOS 14+ SUCCESS (trusting NEHotspotConfigurationManager)"); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } else { + // iOS 11-13: Verify using the old method + NSLog(@"[WifiWizard2] iOSConnectNetwork - iOS 11-13: Verifying connection with legacy method"); + NSDictionary *r = [self fetchSSIDInfo]; + NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; + + if ([ssid isEqualToString:ssidString]){ + NSLog(@"[WifiWizard2] iOSConnectNetwork - iOS 11-13 SUCCESS (verified: %@)", ssid); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; + } else { + NSLog(@"[WifiWizard2] iOSConnectNetwork - iOS 11-13 FAILED (expected: %@, got: %@)", ssidString, ssid); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Connection verification failed"]; + } + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - [self.commandDelegate sendPluginResult:pluginResult - callbackId:command.callbackId]; }]; @@ -100,6 +140,8 @@ - (void)iOSConnectOpenNetwork:(CDVInvokedUrlCommand*)command { if (@available(iOS 11.0, *)) { if (ssidString && [ssidString length]) { + NSLog(@"[WifiWizard2] iOSConnectOpenNetwork - Attempting to connect to open network SSID: %@", ssidString); + NEHotspotConfiguration *configuration = [[NEHotspotConfiguration alloc] initWithSSID:ssidString]; @@ -107,17 +149,44 @@ - (void)iOSConnectOpenNetwork:(CDVInvokedUrlCommand*)command { [[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:^(NSError * _Nullable error) { - NSDictionary *r = [self fetchSSIDInfo]; - - NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; //@"SSID" + if (error) { + // Check if error code is 13 (NEHotspotConfigurationErrorAlreadyAssociated) + // This means we're already connected to this network - treat as success + if (error.code == 13) { + NSLog(@"[WifiWizard2] iOSConnectOpenNetwork - Already connected to SSID: %@", ssidString); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } + // Connection failed with other error + NSLog(@"[WifiWizard2] iOSConnectOpenNetwork - Connection FAILED with error: %@", error.description); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return; + } - if ([ssid isEqualToString:ssidString]){ + // iOS 14+: Trust NEHotspotConfigurationManager result + // CNCopyCurrentNetworkInfo is deprecated and unreliable, requires location permission + if (@available(iOS 14.0, *)) { + // On iOS 14+, if no error was returned, connection is successful + NSLog(@"[WifiWizard2] iOSConnectOpenNetwork - iOS 14+ SUCCESS (trusting NEHotspotConfigurationManager)"); pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; - }else{ - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.description]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } else { + // iOS 11-13: Verify using the old method + NSLog(@"[WifiWizard2] iOSConnectOpenNetwork - iOS 11-13: Verifying connection with legacy method"); + NSDictionary *r = [self fetchSSIDInfo]; + NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; + + if ([ssid isEqualToString:ssidString]){ + NSLog(@"[WifiWizard2] iOSConnectOpenNetwork - iOS 11-13 SUCCESS (verified: %@)", ssid); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssidString]; + } else { + NSLog(@"[WifiWizard2] iOSConnectOpenNetwork - iOS 11-13 FAILED (expected: %@, got: %@)", ssidString, ssid); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Connection verification failed"]; + } + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - [self.commandDelegate sendPluginResult:pluginResult - callbackId:command.callbackId]; }]; @@ -160,35 +229,71 @@ - (void)iOSDisconnectNetwork:(CDVInvokedUrlCommand*)command { } - (void)getConnectedSSID:(CDVInvokedUrlCommand*)command { - CDVPluginResult *pluginResult = nil; - NSDictionary *r = [self fetchSSIDInfo]; - - NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; //@"SSID" - - if (ssid && [ssid length]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssid]; + __block CDVPluginResult *pluginResult = nil; + NSLog(@"[WifiWizard2] getConnectedSSID called"); + + if (@available(iOS 14.0, *)) { + // iOS 14+: Use NEHotspotNetwork.fetchCurrent + NSLog(@"[WifiWizard2] getConnectedSSID - Using iOS 14+ NEHotspotNetwork.fetchCurrent API"); + [NEHotspotNetwork fetchCurrentWithCompletionHandler:^(NEHotspotNetwork * _Nullable currentNetwork) { + if (currentNetwork && currentNetwork.SSID) { + NSLog(@"[WifiWizard2] getConnectedSSID - iOS 14+ SUCCESS: %@", currentNetwork.SSID); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:currentNetwork.SSID]; + } else { + NSLog(@"[WifiWizard2] getConnectedSSID - iOS 14+ FAILED: currentNetwork is nil or no SSID"); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"]; + } + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; } else { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"]; + // iOS 11-13: Use legacy method + NSLog(@"[WifiWizard2] getConnectedSSID - Using iOS 11-13 legacy CNCopyCurrentNetworkInfo"); + NSDictionary *r = [self fetchSSIDInfo]; + NSString *ssid = [r objectForKey:(id)kCNNetworkInfoKeySSID]; + + if (ssid && [ssid length]) { + NSLog(@"[WifiWizard2] getConnectedSSID - iOS 11-13 SUCCESS: %@", ssid); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:ssid]; + } else { + NSLog(@"[WifiWizard2] getConnectedSSID - iOS 11-13 FAILED: No SSID available"); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"]; + } + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - - [self.commandDelegate sendPluginResult:pluginResult - callbackId:command.callbackId]; } - (void)getConnectedBSSID:(CDVInvokedUrlCommand*)command { - CDVPluginResult *pluginResult = nil; - NSDictionary *r = [self fetchSSIDInfo]; - - NSString *bssid = [r objectForKey:(id)kCNNetworkInfoKeyBSSID]; //@"SSID" - - if (bssid && [bssid length]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:bssid]; + __block CDVPluginResult *pluginResult = nil; + NSLog(@"[WifiWizard2] getConnectedBSSID called"); + + if (@available(iOS 14.0, *)) { + // iOS 14+: Use NEHotspotNetwork.fetchCurrent + NSLog(@"[WifiWizard2] getConnectedBSSID - Using iOS 14+ NEHotspotNetwork.fetchCurrent API"); + [NEHotspotNetwork fetchCurrentWithCompletionHandler:^(NEHotspotNetwork * _Nullable currentNetwork) { + if (currentNetwork && currentNetwork.BSSID) { + NSLog(@"[WifiWizard2] getConnectedBSSID - iOS 14+ SUCCESS: %@", currentNetwork.BSSID); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:currentNetwork.BSSID]; + } else { + NSLog(@"[WifiWizard2] getConnectedBSSID - iOS 14+ FAILED: currentNetwork is nil or no BSSID"); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"]; + } + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + }]; } else { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"]; + // iOS 11-13: Use legacy method + NSLog(@"[WifiWizard2] getConnectedBSSID - Using iOS 11-13 legacy CNCopyCurrentNetworkInfo"); + NSDictionary *r = [self fetchSSIDInfo]; + NSString *bssid = [r objectForKey:(id)kCNNetworkInfoKeyBSSID]; + + if (bssid && [bssid length]) { + NSLog(@"[WifiWizard2] getConnectedBSSID - iOS 11-13 SUCCESS: %@", bssid); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:bssid]; + } else { + NSLog(@"[WifiWizard2] getConnectedBSSID - iOS 11-13 FAILED: No BSSID available"); + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not available"]; + } + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - - [self.commandDelegate sendPluginResult:pluginResult - callbackId:command.callbackId]; } - (void)isWifiEnabled:(CDVInvokedUrlCommand*)command { @@ -223,54 +328,54 @@ - (void)scan:(CDVInvokedUrlCommand*)command { - (void)addNetwork:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)removeNetwork:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)androidConnectNetwork:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)androidDisconnectNetwork:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)listNetworks:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)getScanResults:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @@ -286,45 +391,45 @@ - (void)startScan:(CDVInvokedUrlCommand*)command { - (void)disconnect:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)isConnectedToInternet:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)canConnectToInternet:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)canPingWifiRouter:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)canConnectToRouter:(CDVInvokedUrlCommand*)command { CDVPluginResult *pluginResult = nil; - + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not supported"]; - + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; }