iOS Swift以编程方式连接WiFi并区分密码错误和范围内没有WiFi [英] iOS Swift connect WiFi programmatically and distinguish between bad password and no WiFi in range

查看:142
本文介绍了iOS Swift以编程方式连接WiFi并区分密码错误和范围内没有WiFi的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

NEHotspotConfiguration效果很好,但是当我尝试连接的SSID不可用(超出范围或关闭)或我提交的密码不正确时,错误均为nil.

NEHotspotConfiguration works well, but the error is nil both when the SSID I am trying to connect to is not available (out of range or off) or when the password I've submitted is incorrect.

我做错了什么?我希望能够区分这两种情况,以便相应地通知用户.

What am I doing wrong? I want to be able to distinguish between these two scenarios so I can inform the user accordingly.

代码段:

func connect(ssid: String, password: String, completionHandler: @escaping(Bool?, String?) -> Void) {
    activityIndicatorView?.startAnimating()

    guard !isAlreadyConnected(ssid: ssid) else {
        activityIndicatorView?.stopAnimating()
        completionHandler(true, nil)
        return;
    }

    let hotspotConfig = NEHotspotConfiguration(ssid: ssid, passphrase: password, isWEP: false)//Secured connections
    hotspotConfig.joinOnce = true

    NEHotspotConfigurationManager.shared.apply(hotspotConfig) {[weak self] (error) in
        guard let self = self else { return; }

        self.activityIndicatorView?.stopAnimating()
        if let error = error {
            completionHandler(false, error.localizedDescription)
        }
        else {
            let ssids = self.currentSSIDs()
            if ssids.count > 0 && ssids.first == ssid {
                completionHandler(true, nil)
            } else {
                completionHandler(false, error?.localizedDescription ?? "An error occured")
            }
        }
    }
}

推荐答案

快速尝试一下,它看起来完全可重复. 进一步的研究表明,这是Apple的错误. 因此答案是:您没有做错任何事情,这是一个错误.

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.

原因似乎是:

...通过完成处理程序看到的错误是与框架本身相关的那些错误.一旦请求通过网络扩展框架,一直到Wi-Fi子系统,错误就会显示给用户,而不是传递给完成处理程序.这是否是一个错误尚待争论.

...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.

以后的人可以阅读:

因此,我关于NEHotspot的2个错误(46628017和46579891)被标记为重复的42919071

So my 2 bugs (46628017 and 46579891) regarding the NEHotspot marked as duplicated of 42919071

在此处查看整个讨论: https://forums.developer.apple.com/thread/96834

see the whole discussion here: https://forums.developer.apple.com/thread/96834

一些实验

有一个很好的答案: https://stackoverflow.com/a/5198968/2331445

它显示了如何访问有关当前连接的WIFI的信息.

It shows how to access information about the currently connected WIFI.

正如作者所解释的,您需要为iOS> 12添加访问WiFi信息功能.使用上述SO答案中的getConnectedWifiInfo方法进行的测试可能如下所示:

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

此SO答案的作者还显示了适用于较旧iOS版本的方法.

The author of this SO answer also shows methods for older iOS versions.

这篇关于iOS Swift以编程方式连接WiFi并区分密码错误和范围内没有WiFi的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆