feat(network): add local network auto-switch feature (#1334)

This commit is contained in:
Fredrik Burmester
2026-01-11 13:08:14 +01:00
committed by GitHub
parent ac9ac5d423
commit 467bea7192
17 changed files with 823 additions and 70 deletions

View File

@@ -0,0 +1,8 @@
{
"name": "wifi-ssid",
"version": "1.0.0",
"platforms": ["ios"],
"ios": {
"modules": ["WifiSsidModule"]
}
}

View File

@@ -0,0 +1,45 @@
import { Platform, requireNativeModule } from "expo-modules-core";
// Only load the native module on iOS
const WifiSsidModule =
Platform.OS === "ios" ? requireNativeModule("WifiSsid") : null;
/**
* Get the current WiFi SSID on iOS.
* Returns null on Android or if not connected to WiFi.
*
* Requires:
* - Location permission granted
* - com.apple.developer.networking.wifi-info entitlement
* - Access WiFi Information capability enabled in Apple Developer Portal
*/
export async function getSSID(): Promise<string | null> {
if (!WifiSsidModule) {
console.log("[WifiSsid] Module not available on this platform");
return null;
}
try {
const ssid = await WifiSsidModule.getSSID();
return ssid ?? null;
} catch (error) {
console.error("[WifiSsid] Error getting SSID:", error);
return null;
}
}
/**
* Synchronous version - uses older CNCopyCurrentNetworkInfo API
*/
export function getSSIDSync(): string | null {
if (!WifiSsidModule) {
return null;
}
try {
return WifiSsidModule.getSSIDSync() ?? null;
} catch (error) {
console.error("[WifiSsid] Error getting SSID (sync):", error);
return null;
}
}

View File

@@ -0,0 +1,22 @@
Pod::Spec.new do |s|
s.name = 'WifiSsid'
s.version = '1.0.0'
s.summary = 'Get WiFi SSID on iOS'
s.description = 'Native iOS module to get current WiFi SSID using NEHotspotNetwork'
s.author = ''
s.homepage = 'https://docs.expo.dev/modules/'
s.platforms = { :ios => '15.6', :tvos => '15.0' }
s.source = { git: '' }
s.static_framework = true
s.dependency 'ExpoModulesCore'
s.frameworks = 'NetworkExtension', 'SystemConfiguration'
s.pod_target_xcconfig = {
'DEFINES_MODULE' => 'YES',
'SWIFT_COMPILATION_MODE' => 'wholemodule'
}
s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}"
end

View File

@@ -0,0 +1,52 @@
import ExpoModulesCore
import NetworkExtension
import SystemConfiguration.CaptiveNetwork
public class WifiSsidModule: Module {
public func definition() -> ModuleDefinition {
Name("WifiSsid")
// Get current WiFi SSID using NEHotspotNetwork (iOS 14+)
AsyncFunction("getSSID") { () -> String? in
return await withCheckedContinuation { continuation in
NEHotspotNetwork.fetchCurrent { network in
if let ssid = network?.ssid {
print("[WifiSsid] Got SSID via NEHotspotNetwork: \(ssid)")
continuation.resume(returning: ssid)
} else {
// Fallback to CNCopyCurrentNetworkInfo for older iOS
print("[WifiSsid] NEHotspotNetwork returned nil, trying CNCopyCurrentNetworkInfo")
let ssid = self.getSSIDViaCNCopy()
continuation.resume(returning: ssid)
}
}
}
}
// Synchronous version using only CNCopyCurrentNetworkInfo
Function("getSSIDSync") { () -> String? in
return self.getSSIDViaCNCopy()
}
}
private func getSSIDViaCNCopy() -> String? {
guard let interfaces = CNCopySupportedInterfaces() as? [String] else {
print("[WifiSsid] CNCopySupportedInterfaces returned nil")
return nil
}
for interface in interfaces {
guard let networkInfo = CNCopyCurrentNetworkInfo(interface as CFString) as? [String: Any] else {
continue
}
if let ssid = networkInfo[kCNNetworkInfoKeySSID as String] as? String {
print("[WifiSsid] Got SSID via CNCopyCurrentNetworkInfo: \(ssid)")
return ssid
}
}
print("[WifiSsid] No SSID found via CNCopyCurrentNetworkInfo")
return nil
}
}