iOS Swift 以编程方式连接 WiFi 并区分密码错误和范围内没有 WiFi

2024-02-03

NEHotspotConfiguration工作正常,但错误是nil当我尝试连接的 SSID 不可用(超出范围或关闭)或我提交的密码不正确时。

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

代码片段:

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")
            }
        }
    }
}

快速尝试了一下,它似乎可以完美重现。 进一步的研究表明这是苹果的一个错误。 所以答案是:你没有做错什么,这是一个错误。

原因似乎是:

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

稍后可以读到:

所以我的 2 个关于 NEHotspot 的错误(46628017 和 46579891)被标记为与 42919071 重复

请参阅此处的整个讨论:https://forums.developer.apple.com/thread/96834 https://forums.developer.apple.com/thread/96834

一些实验

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

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

正如作者所解释的,您需要添加接入WiFi信息能力对于 iOS > 12。使用上述实验答案中的 getConnectedWifiInfo 方法进行的测试可能如下所示:

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
    }

}

事实上,如果我运行这段代码,我会得到以下结果:

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 版本的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS Swift 以编程方式连接 WiFi 并区分密码错误和范围内没有 WiFi 的相关文章

  • 在 Swift 中向 UIButton 添加字符串属性

    如何将字符串属性与UIButton在斯威夫特 我不希望该字符串显示为按钮文本 而只是将其作为标识符或键分配给按钮 这是我到目前为止所拥有的 func createAnswerButtons var index Int for index 0
  • 将 NSDecimalNumber 转换为 NSString

    我正在从如下所示的对象中检索密钥 po obj TypeID 3 TypeName Asset 键值的检索方式如下 NSString typeId NSString obj objectForKey TypeID typeId 不是 NSS
  • 如何在导航栏中添加右键?

    我有一个问题要在导航栏中添加右键 我有两个视图 视图 A 和视图 B 我添加了一个导航栏来查看A 之后我使用了self navigationController pushViewController显示视图 B 视图B的导航栏左侧自动显示一
  • 清空 Firebase DatabaseReference 不会停止观察,这绝对正确吗?

    In the Firebase 太棒了 你做这个 var r1 DatabaseReference nil 然后这个 r1 Database database reference withPath score bucks r1 observ
  • Xcode 8 beta“错误”对于这种情况下的类型查找不明确

    根据这篇文章 我需要指定模块来查找对象类型 在此上下文中 方法 对于类型查找不明确 Alamofire 中的错误 https stackoverflow com questions 33543597 method is ambiguous
  • iOS App Today 扩展未上传到物理设备

    我正在为我的应用程序创建一个今日小部件http budgt ch http budgt ch因为一些用户要求快速访问关键功能 初步 扩展在 iOS 模拟器上运行良好 安装如下 1 安装最新的容器应用程序 2 安装以 今天 为容器的扩展 但是
  • 调整 SKShapeNode 的大小

    如何调整 SKShapeNode 的大小 到目前为止我尝试过的 调整框架大小 box frame width 10 给出错误Cannot assign to the result of this expression SKAction le
  • UITextField 文本更改事件

    如何检测文本字段中的任何文本更改 委托方法shouldChangeCharactersInRange适用于某些东西 但它并不能完全满足我的需求 因为在它返回 YES 之前 textField 文本不可用于其他观察者方法 例如在我的代码中ca
  • @Font-face 不适用于 IOS

    我正在开发一个 WordPress 网站 并且在每个页面上都有一个 H1 标签作为该页面的标题 我正在使用 font face 的特殊字体 它在每个浏览器的 Windows 上都运行良好 但是当我切换到 Mac 时 它不会显示 h1 标签
  • 如何在 AVAudioSession 内使用 iPhone XS 中内置的立体声(2 通道)麦克风?

    我试图从 iPhone XS 的所谓立体声后置麦克风获取两个通道 但在不同位置只能看到一个通道AVAudioSession and AVAudioSessionPortDescription与后置摄像头相关联 我尝试过使用AVAudioSe
  • Swift - 本地通知不会被触发

    我正在 Swift 3 中编码 我只是想发送通知now没有任何延迟或间隔 然而 通知永远不会被触发 这是我的代码 视图控制器代码 import UserNotifications class HomeViewController UIVie
  • 在 Android 上使用 opus 剪辑从 IOS 发送的声音

    我正在 IOS 中从 audioUnit 录制音频 用 opus 编码字节并通过 UDP 将其发送到 android 端 问题是播放的声音有点削波 我还通过将原始数据从 IOS 发送到 Android 来测试声音 效果非常完美 我的 Aud
  • 允许的 APNS 持续连接数量是多少?

    我正在尝试编写服务器端代码来为我的应用程序发送推送通知 根据 Apple 的建议 我计划保留连接并根据需要发送推送通知 Apple 还允许打开和保留多个并行连接以发送推送通知 您可以与同一网关或多个网关实例建立多个并行连接 为此 我想维护一
  • iOS 中如何清除特定域的 cookie?

    我已经搜索了 StackOverflow 上的几乎所有问题来寻找我的问题的答案 我还没有找到任何有用的链接或教程来说明哪种方式最好清除特定域的 cookie 如果有人可以帮助我 请 我自己找到了解决方案 如果您想删除 UIWebView 中
  • 如何建立辅助NSSortDescriptor排序键?

    我已成功按排序键对数据进行排序lastName 但我想知道如何排序lastName 然后由firstName 这是我用来排序的代码lastName NSSortDescriptor sortDescriptor NSSortDescript
  • 如何在 iOS 上压缩 Realm DB?

    我想定期压缩 iOS 上的 Realm 实例以回收空间 我认为该过程是将数据库复制到临时位置 然后将其复制回来并使用新的default realm 文件 我的问题是Realm 其行为就像单例并回收对象 因此我无法真正关闭它并告诉它打开新的
  • Swift 中的“funcobserveValueForKeyPath(keyPath:NSString,object:AnyObject,change:NSDictionary,context:Void)”问题

    我已经为 AVPlayer 添加了一个观察者 如下所示 self audioPlayer addObserver self forKeyPath currentItem status options NSKeyValueObservingO
  • 如何使 SFSpeechRecognizer 在 macOS 上可用?

    我正在尝试使用 Apple 的语音框架在 macOS 10 15 1 上进行语音识别 在 macOS 10 15 之前 语音识别仅在 iOS 上可用 但根据文档 https developer apple com documentation
  • 如何在 SwiftUI 中将阴影应用于内部视图?

    我在周围添加了阴影VStack其中包含我的两个文本字段和一个提交按钮 然而 阴影也被应用到了文本框内的两个文本字段 VStack 我在这里缺少什么导致这种情况发生吗 我尝试添加shadow radius 0 在文本字段上 但它不会改变任何内
  • 当应用程序退出活动状态时,MPMovies PlayerViewController 被解雇

    当我将 iPhone 设置为睡眠状态 切换到另一个应用程序等 然后再次返回时 之前的可见内容MPMoviePlayerViewController 提出与presentMoviePlayerViewControllerAnimated 已经

随机推荐

  • 在nodejs工作线程内调用函数

    这是我的工人 const Worker require worker threads const worker new Worker function hello console log hello world eval true work
  • Apache tomcat7 作为 Windows 服务

    我正在尝试为 Apache tomcat 7 0 45 创建 Windows 服务 在 Windows 版本 7 中 我执行了这个 C tomcat7 bin gt service install Mytomcat7 Windows 服务已
  • 处理阻塞 .NET 套接字的超时

    使用 Accept 方法创建的 TcpClient 实例用于管理客户端连接 当我需要终止服务器线程时就会出现问题 因为它在接收调用时被阻塞 所以我设置了一个 TcpClient ReceiveTimeout 以便循环每个n毫秒来测试退出条件
  • 如何用python创建0年的日期时间对象

    正如标题所说 如果我尝试这样做 它会给我一个年份值的 ValueError 但我想要一个年份为 0 的日期时间 有什么方法可以做到这一点吗 从文档 datetime 模块导出以下常量 datetime MINYEAR 日期或中允许的最小年份
  • 使用 Office365 SMTP 设置 PHPMailer

    我正在尝试设置 PHPMailer 以便我们的一位客户能够从他们自己的帐户自动生成电子邮件 我登录了他们的Office 365帐户 发现PHPMailer所需的设置是 Host smtp office365 com Port 587 Aut
  • Doctrine 2.3 实体生成器:样本、文档?

    Doctrine 可以基于小数据输入生成实体 包括关系信息 但是 我未能找到有关该主题的任何示例或简明信息 官方文档只有一小段 有一个小的命令行示例 完全没有解释什么 任何人都可以参考这方面的书籍 文章甚至代码示例吗 首先你需要引导程序Do
  • 当键盘存在时,如何使 UITextField 向上移动 - 开始编辑?

    使用 iOS SDK 我有一个UIView with UITextField调出键盘 我需要它能够 允许滚动内容UIScrollView键盘打开后即可查看其他文本字段 自动 跳跃 通过向上滚动 或缩短 我知道我需要一个UIScrollVie
  • iPhone 开发 - 开发和分发配置之间有什么区别?

    我无法在苹果文档中找到关于两者之间区别的明确解释发展 and 分配供应 我目前正在使用开发配置在我的 iPhone 上进行开发和测试 我打算将该应用程序分发到我的 Beta 测试中 我想知道 我需要使用吗分配供应 我应该为每个单独的测试人员
  • Android:获取列中的最高值

    我有一个指向内容的 URL 我需要获取其中一列中包含的最高值 是否有任何聚合函数可以完成该任务 或者我必须手动执行此操作 如果您正在查询 Android 内容提供商 您应该能够通过传递来实现此目的MAX COLUMN NAME 进入选择参数
  • 运行脚本标签是否会阻止其他脚本标签的下载?

    这是来自索引 html in HTML5 样板 https github com h5bp html5 boilerplate blob master index html 就在之前 tag
  • 如何在 C++ 中使用带有用户输入的枚举

    我正在制作一个简单的剪刀石头布游戏 我需要使用枚举数据结构 我的问题是 由于从 int userInput 到 Throws userThrow 的转换无效 我无法编译以下代码 enum Throws R P S int userInput
  • 如何启用 Qt5 中已弃用的功能

    我想将 Qt4 程序移植到 Qt5 并且某些函数未定义 例如 QHeaderView setMoveable 但我在 qheaderview h 文件中看到 通过一些神奇的定义 QT DEPRECATED SINCE 应该可以重新启用它们
  • 如何检查一个句柄是否应该关闭?

    如果 ShellExecuteEx 返回 false 是否应该关闭句柄 function EditAndWait const AFileName string boolean var Info TShellExecuteInfo begin
  • UILocalNotification 在 iOS 10 中已弃用

    这可能是一个提前的问题 但我想知道用什么代替UILocalNotification在 iOS 10 中 我正在开发一个具有部署目标 iOS 8 的应用程序 所以可以使用吗UILocalNotification 是的 您可以使用UILocal
  • 如何在线程中使用notifyDataSetChanged()

    我创建一个线程来更新我的数据并尝试这样做notifyDataSetChanged在我的列表视图中 private class ReceiverThread extends Thread Override public void run up
  • 通过后退按钮关闭 Ionic 4 中的模态框

    我有一个Modal in Ionic 4 我想close它 当用户按下返回键在她的手机上 或浏览器中的后退按钮 有谁知道我该怎么做 编辑 更多细节 我有一个打开模式的按钮 async onClick const modal await th
  • 在 C# 中检查来自不同类的变量

    问候 我有2节课 一个称为 程序 另一个称为 日志 名为 Programs 的类有public const string m sEnviron 在顶部附近 我需要通过名为 Logs 的类检查 m sEnviron 变量设置的内容 变量 m
  • 在 Django/Python 中标准化街道地址

    我有一个 Django 表单 其中一个字段是TextInput街道地址 我想标准化数据 例如 gt gt normalize 420 East 24th St 420 E 24th Street gt gt normalize 221 Am
  • 使用 100% cpu 的相对简单的 Python 脚本

    我不会提供代码 因为它太长了 python 脚本涉及执行在 while 循环中运行的大量命令 基本结构 while True The meat goes here with the odd if and stuff 现在我已经完成了它 我注
  • iOS Swift 以编程方式连接 WiFi 并区分密码错误和范围内没有 WiFi

    NEHotspotConfiguration工作正常 但错误是nil当我尝试连接的 SSID 不可用 超出范围或关闭 或我提交的密码不正确时 我究竟做错了什么 我希望能够区分这两种情况 以便我可以相应地通知用户 代码片段 func conn