iOS Swift connect WiFi programmatically and distinguish between bad password and no WiFi in range
Quickly tried it and it is perfectly reproducible it seems.
Further research revealed that it is an Apple error.
So the answer is: You are nothing doing wrong, it's a bug.
Reasons seems to be:
...the errors that you see via the completion handler are those errors related to the framework itself. Once the request has made it past the Network Extension framework, down to the Wi-Fi subsystem, errors are displayed to the user rather than delivered to your completion handler. Whether that’s a bug is up for debate.
Later down one can read:
So my 2 bugs (46628017 and 46579891) regarding the NEHotspot marked as duplicated of 42919071
see the whole discussion here:
https://forums.developer.apple.com/thread/96834
Some Experiment
There is this nice SO answer: https://stackoverflow.com/a/5198968/2331445
It shows how to access information about the currently connected WIFI.
As the author explains, you need to add the Access WiFi Information capability for iOS > 12. A test using the getConnectedWifiInfo method from the above SO answer for an experiment might look like this:
import UIKit
import NetworkExtension
import SystemConfiguration.CaptiveNetwork
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func onConnect(_ sender: Any) {
let configuration = NEHotspotConfiguration.init(ssid: "somessid", passphrase: "somepassphrase", isWEP: false)
configuration.joinOnce = true
NEHotspotConfigurationManager.shared.apply(configuration) { [weak self] (error) in
print("error is \(String(describing: error))")
if let error = error {
let nsError = error as NSError
if nsError.domain == "NEHotspotConfigurationErrorDomain" {
if let configError = NEHotspotConfigurationError(rawValue: nsError.code) {
switch configError {
case .invalidWPAPassphrase:
print("password error: \(error.localizedDescription)")
case .invalid, .invalidSSID, .invalidWEPPassphrase,
.invalidEAPSettings, .invalidHS20Settings, .invalidHS20DomainName, .userDenied, .pending, .systemConfiguration, .unknown, .joinOnceNotSupported, .alreadyAssociated, .applicationIsNotInForeground, .internal:
print("other error: \(error.localizedDescription)")
@unknown default:
print("later added error: \(error.localizedDescription)")
}
}
} else {
print("some other error: \(error.localizedDescription)")
}
} else {
print("perhaps connected")
self?.printWifiInfo()
}
}
}
@IBAction func onInfo(_ sender: Any) {
self.printWifiInfo()
}
private func printWifiInfo() {
print("printWifiInfo:")
if let wifi = self.getConnectedWifiInfo() {
if let connectedSSID = wifi["SSID"] {
print("we are currently connected with \(connectedSSID)")
}
print("further info:")
for (k, v) in wifi {
print(". \(k) \(v)")
}
}
print()
}
private func getConnectedWifiInfo() -> [AnyHashable: Any]? {
if let ifs = CFBridgingRetain( CNCopySupportedInterfaces()) as? [String],
let ifName = ifs.first as CFString?,
let info = CFBridgingRetain( CNCopyCurrentNetworkInfo((ifName))) as? [AnyHashable: Any] {
return info
}
return nil
}
}
And indeed if I run this code I get as result:
error is nil
perhaps connected
printWifiInfo:
we are currently connected with somessid
further info:
. SSIDDATA <11111111 22222222 333331333 44444444 55>
. BSSID 70:33:ab:cd:ef:22
. SSID somessid
The author of this SO answer also shows methods for older iOS versions.
Distinguish between open and password locked available WiFi networks
Assuming this is a system with NetworkManager then QNetworkConfiguration::identifier()
will return the D-Bus ObjectPath of the NetworkManager configuration item.
I.e. you could use QtDBus to call the org.freedesktop.NetworkManager.Settings.Connection.GetSettings()
method on that object which I think should include the information you are looking for
How to programmatically connect to a WiFi network given the SSID and password
With iOS 11, Apple provided public API you can use to programmatically join a WiFi network without leaving your app.
The class you’ll need to use is called NEHotspotConfiguration
.
To use it, you need to enable the Hotspot
capability in your App Capabilities (Adding Capabilities). Quick working example :
NEHotspotConfiguration *configuration = [[NEHotspotConfiguration
alloc] initWithSSID:@“SSID-Name”];
configuration.joinOnce = YES;
[[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:nil];
This will prompt the user to join the “SSID-Name” WiFi network. It will stay connected to the WiFi until the user leaves the app.
This doesn't work with the simulator you need to run this code with an actual device to make it work.
More informations here :
https://developer.apple.com/documentation/networkextension/nehotspotconfiguration
iOS VPN on Demand rules
You should read the rules like a set of firewall rules, NEVPNManager
goes through the list of rules and the first rule that applies is followed. In your example when you would switch off cellular data it will evaluate rule 1: wifi + SSID "ABC". If that rules satisfies i.e. you are connected to WiFi SSID "ABC", the vpn will be connected. If not, NEVPNManager
will go through the next rule.
If you switch off cellular, the first rule still applies. (You can still have a WiFi connection). NEVPNManager
can't differentiate between cellular on/off. It can only differentiate between which interface is used: cellular, WiFi or any.
Related Topics
How to Handle Local Notification When App Has Been Terminated
How to Add a Ibaction to a Button Programmatically in Swift 4
How to Rotate a Scnsphere Using a Pan Gesture Recognizer
Self Sizing Uitextview Till Specific Height
Wkwebview Blank After 'Successful' Https Nsurlrequest
Correct Way to Layout Swiftui (Similar to Autolayout)
Items in File Provider Extension for iOS 11
Swiftui Multiple Navigationlinks in Form/Sheet - Entry Stays Highlighted
Finding It Difficult to Pass Data to Separate Viewcontroller
What Are the First Two Columns in Scnmatrix4
Xcode 6 & Swift: Black Bars Appear Above and Below the Viewcontroller on iOS 7 iPhone 5 Device
Swift - Using Cgcontext to Draw with Finger
How Is It I Can Animate the Change in Bar Tint Color of a Uinavigationbar But Not a Uitabbar
Blur Effect - Background Uitextfield
How to Handle Homophones in Speech Recognition
Settitletextattributes Doesn't Work for Uitabbaritem When It Is Unselected in Swift