mirror of
https://github.com/home-assistant/iOS.git
synced 2026-02-15 16:41:00 -06:00
Added calls to syncNetworkInformation() at the start of various perform() methods for AppIntents and widget controls to ensure up-to-date connectivity data before executing actions. Also refactored ConnectivityWrapper to support async network info synchronization. <!-- Thank you for submitting a Pull Request and helping to improve Home Assistant. Please complete the following sections to help the processing and review of your changes. Please do not delete anything from this template. --> ## Summary <!-- Provide a brief summary of the changes you have made and most importantly what they aim to achieve --> ## Screenshots <!-- If this is a user-facing change not in the frontend, please include screenshots in light and dark mode. --> ## Link to pull request in Documentation repository <!-- Pull requests that add, change or remove functionality must have a corresponding pull request in the Companion App Documentation repository (https://github.com/home-assistant/companion.home-assistant). Please add the number of this pull request after the "#" --> Documentation: home-assistant/companion.home-assistant# ## Any other notes <!-- If there is any other information of note, like if this Pull Request is part of a bigger change, please include it here. --> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
146 lines
5.0 KiB
Swift
146 lines
5.0 KiB
Swift
import Foundation
|
|
#if os(iOS)
|
|
import CoreTelephony
|
|
import Reachability
|
|
#endif
|
|
import Communicator
|
|
import NetworkExtension
|
|
|
|
/// Wrapper around CoreTelephony, Reachability
|
|
public class ConnectivityWrapper {
|
|
public var connectivityDidChangeNotification: () -> Notification.Name
|
|
public var hasWiFi: () -> Bool
|
|
public var currentWiFiSSID: () -> String?
|
|
public var currentWiFiBSSID: () -> String?
|
|
public var currentNetworkHardwareAddress: () -> String?
|
|
public var simpleNetworkType: () -> NetworkType
|
|
public var cellularNetworkType: () -> NetworkType
|
|
public var networkAttributes: () -> [String: Any]
|
|
|
|
#if targetEnvironment(macCatalyst)
|
|
init() {
|
|
self.hasWiFi = { Current.macBridge.networkConnectivity.hasWiFi }
|
|
self.currentWiFiSSID = { Current.macBridge.networkConnectivity.wifi?.ssid }
|
|
self.currentWiFiBSSID = { Current.macBridge.networkConnectivity.wifi?.bssid }
|
|
self.connectivityDidChangeNotification = { Current.macBridge.networkConnectivityDidChangeNotification }
|
|
self.simpleNetworkType = {
|
|
switch Current.macBridge.networkConnectivity.networkType {
|
|
case .ethernet: return .ethernet
|
|
case .wifi: return .wifi
|
|
case .unknown: return .unknown
|
|
case .noNetwork: return .noConnection
|
|
}
|
|
}
|
|
self.currentNetworkHardwareAddress = { Current.macBridge.networkConnectivity.interface?.hardwareAddress }
|
|
self.cellularNetworkType = { .unknown }
|
|
self.networkAttributes = {
|
|
if let interface = Current.macBridge.networkConnectivity.interface {
|
|
return [
|
|
"Name": interface.name,
|
|
"Hardware Address": interface.hardwareAddress,
|
|
]
|
|
} else {
|
|
return [:]
|
|
}
|
|
}
|
|
}
|
|
|
|
#elseif os(iOS)
|
|
init() {
|
|
let reachability = try? Reachability()
|
|
|
|
do {
|
|
try reachability?.startNotifier()
|
|
} catch {
|
|
Current.Log.error("failed to start reachability notifier: \(error)")
|
|
}
|
|
self.hasWiFi = { true }
|
|
self.currentWiFiSSID = {
|
|
nil
|
|
}
|
|
self.currentWiFiBSSID = {
|
|
nil
|
|
}
|
|
self.connectivityDidChangeNotification = { .reachabilityChanged }
|
|
self.simpleNetworkType = { reachability?.getSimpleNetworkType() ?? .unknown }
|
|
self.cellularNetworkType = { reachability?.getNetworkType() ?? .unknown }
|
|
self.currentNetworkHardwareAddress = { nil }
|
|
self.networkAttributes = { [:] }
|
|
|
|
syncNetworkInformation()
|
|
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(connectivityDidChange(_:)),
|
|
name: .reachabilityChanged,
|
|
object: nil
|
|
)
|
|
}
|
|
#else
|
|
init() {
|
|
self.hasWiFi = { true }
|
|
self.currentWiFiSSID = {
|
|
let ssid = WatchUserDefaults.shared.string(for: .watchSSID)
|
|
Current.Log.verbose("Watch current WiFi SSID: \(String(describing: ssid))")
|
|
return ssid
|
|
}
|
|
self.currentWiFiBSSID = { nil }
|
|
self.connectivityDidChangeNotification = { .init(rawValue: "_noop_") }
|
|
self.simpleNetworkType = { .unknown }
|
|
self.cellularNetworkType = { .unknown }
|
|
self.currentNetworkHardwareAddress = { nil }
|
|
self.networkAttributes = { [:] }
|
|
|
|
syncNetworkInformation()
|
|
// Reachability observer is not available for watchOS
|
|
}
|
|
#endif
|
|
|
|
#if os(iOS) && !targetEnvironment(macCatalyst)
|
|
public var telephonyCarriers: () -> [String: CTCarrier]? = {
|
|
CTTelephonyNetworkInfo().serviceSubscriberCellularProviders
|
|
}
|
|
|
|
public var telephonyRadioAccessTechnology: () -> [String: String]? = {
|
|
CTTelephonyNetworkInfo().serviceCurrentRadioAccessTechnology
|
|
}
|
|
#endif
|
|
|
|
@objc private func connectivityDidChange(_ note: Notification) {
|
|
syncNetworkInformation()
|
|
}
|
|
|
|
// TODO: Refactor SSID retrieval to be async instead of hacking around with completion handlers
|
|
public func syncNetworkInformation(completion: (() -> Void)? = nil) {
|
|
#if targetEnvironment(macCatalyst)
|
|
// macOS uses macBridge to retrieve network information
|
|
completion?()
|
|
#else
|
|
NEHotspotNetwork.fetchCurrent { hotspotNetwork in
|
|
Current.Log
|
|
.verbose(
|
|
"Current SSID: \(String(describing: hotspotNetwork?.ssid)), current BSSID: \(String(describing: hotspotNetwork?.bssid))"
|
|
)
|
|
let ssid = hotspotNetwork?.ssid
|
|
self.currentWiFiSSID = {
|
|
#if targetEnvironment(simulator)
|
|
return "Simulator"
|
|
#endif
|
|
return ssid
|
|
}
|
|
let bssid = hotspotNetwork?.bssid
|
|
self.currentWiFiBSSID = { bssid }
|
|
completion?()
|
|
}
|
|
#endif
|
|
}
|
|
|
|
public func syncNetworkInformation() async {
|
|
await withCheckedContinuation { continuation in
|
|
syncNetworkInformation {
|
|
continuation.resume()
|
|
}
|
|
}
|
|
}
|
|
}
|