// Author: fruit.com.cn import CoreTelephony import Flutter import Foundation /// 监听系统无线数据选择,并用 URLSession 唤起系统选择框。 final class WirelessDataPrompt { static let channelName = "com.stormg.lumadrama/wireless-data" static let awaitDecisionMethod = "awaitDecision" /// 系统选择框由 URLSession 触发,Dart 的 Socket 请求不会弹出。 private static let promptURL = URL(string: "https://captive.apple.com/hotspot-detect.html") private let cellularData = CTCellularData() private let lock = NSLock() private var pending: [FlutterResult] = [] private var decided = false private var didRequestPrompt = false init() { cellularData.cellularDataRestrictionDidUpdateNotifier = { [weak self] state in DispatchQueue.main.async { self?.completeIfDecided(state) } } } /// 应用进入前台后请求一次,促使系统弹出无线数据选择。 func requestSystemPrompt() { guard !didRequestPrompt, let promptURL = Self.promptURL else { return } didRequestPrompt = true _ = cellularData.restrictedState URLSession.shared.dataTask(with: promptURL) { _, _, _ in }.resume() } /// 未允许前先挂起;用户允许无线数据后再放行。 func awaitDecision(_ result: @escaping FlutterResult) { lock.lock() if decided { lock.unlock() DispatchQueue.main.async { result(nil) } return } pending.append(result) lock.unlock() } private func completeIfDecided(_ state: CTCellularDataRestrictedState) { if state != .notRestricted { return } lock.lock() if decided { lock.unlock() return } decided = true let waiters = pending pending.removeAll() lock.unlock() waiters.forEach { $0(nil) } } }