|
|
import Foundation
|
|
|
import NetworkExtension
|
|
|
import UIKit
|
|
|
import Combine
|
|
|
|
|
|
class WiFiConnectionManager: ObservableObject {
|
|
|
@Published var isConnecting = false
|
|
|
@Published var connectionStatus: ConnectionStatus = .idle
|
|
|
|
|
|
enum ConnectionStatus {
|
|
|
case idle
|
|
|
case connecting
|
|
|
case connected
|
|
|
case failed(String)
|
|
|
}
|
|
|
|
|
|
static let shared = WiFiConnectionManager()
|
|
|
|
|
|
private init() {}
|
|
|
|
|
|
func connectToWiFi(ssid: String, password: String, completion: @escaping (Bool, String?) -> Void) {
|
|
|
guard #available(iOS 11.0, *) else {
|
|
|
completion(false, "iOS 11+ required for WiFi connection")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
DispatchQueue.main.async {
|
|
|
self.isConnecting = true
|
|
|
self.connectionStatus = .connecting
|
|
|
}
|
|
|
|
|
|
// 创建WiFi配置
|
|
|
let configuration = NEHotspotConfiguration(ssid: ssid, passphrase: password, isWEP: false)
|
|
|
configuration.joinOnce = true
|
|
|
|
|
|
// 应用配置
|
|
|
NEHotspotConfigurationManager.shared.apply(configuration) { [weak self] error in
|
|
|
DispatchQueue.main.async {
|
|
|
self?.isConnecting = false
|
|
|
|
|
|
if let error = error {
|
|
|
let errorMessage = self?.handleWiFiError(error)
|
|
|
self?.connectionStatus = .failed(errorMessage ?? "Unknown error")
|
|
|
completion(false, errorMessage)
|
|
|
} else {
|
|
|
self?.connectionStatus = .connected
|
|
|
completion(true, nil)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private func handleWiFiError(_ error: Error) -> String {
|
|
|
let errorCode = (error as NSError).code
|
|
|
|
|
|
switch errorCode {
|
|
|
case NEHotspotConfigurationError.userDenied.rawValue:
|
|
|
return "wifi_user_denied".localized
|
|
|
case NEHotspotConfigurationError.alreadyAssociated.rawValue:
|
|
|
return "wifi_already_connected".localized
|
|
|
case NEHotspotConfigurationError.invalidSSID.rawValue:
|
|
|
return "wifi_invalid_ssid".localized
|
|
|
case NEHotspotConfigurationError.invalidWPAPassphrase.rawValue:
|
|
|
return "wifi_invalid_password".localized
|
|
|
default:
|
|
|
return "wifi_connection_failed".localized
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func resetStatus() {
|
|
|
DispatchQueue.main.async {
|
|
|
self.connectionStatus = .idle
|
|
|
self.isConnecting = false
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// MARK: - WiFi连接扩展
|
|
|
extension WiFiConnectionManager {
|
|
|
func connectWithFallback(ssid: String, password: String, completion: @escaping (Bool, String?) -> Void) {
|
|
|
connectToWiFi(ssid: ssid, password: password) { [weak self] success, error in
|
|
|
if success {
|
|
|
completion(true, nil)
|
|
|
} else {
|
|
|
// 如果NEHotspotConfiguration失败,尝试降级方案
|
|
|
self?.tryFallbackConnection(ssid: ssid, password: password, completion: completion)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private func tryFallbackConnection(ssid: String, password: String, completion: @escaping (Bool, String?) -> Void) {
|
|
|
// 尝试打开系统WiFi设置
|
|
|
let systemWifiURLString = "App-Prefs:root=WIFI"
|
|
|
if let url = URL(string: systemWifiURLString) {
|
|
|
if UIApplication.shared.canOpenURL(url) {
|
|
|
UIApplication.shared.open(url) { success in
|
|
|
if success {
|
|
|
completion(false, "wifi_opened_settings".localized)
|
|
|
} else {
|
|
|
completion(false, String(format: "wifi_manual_setup_instruction".localized, ssid, password))
|
|
|
}
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 最终降级方案:显示手动设置指导
|
|
|
completion(false, String(format: "wifi_manual_setup_instruction".localized, ssid, password))
|
|
|
}
|
|
|
}
|