Hammerspoon 里用 WiFi SSID 做判断的折腾记录

20260530013535_NHoXdgx3.webp

背景

其实需求很简单,就是想在 hammerspoon 里加个功能:当我连着公司的 iHome WiFi 时,鼠标高亮用 home.png;到了别的地方换成 work.png。WiFi 名大概长这样:ihome.6500.5gihome.ax9000.5g 这种。

踩坑过程

第一次尝试:hs.wifi.currentNetwork()

想着这不是很简单嘛,搜了一下官方文档,直接调 hs.wifi.currentNetwork() 不就行了:

1
2
local ssid = hs.wifi.currentNetwork()
print("当前 WiFi ssid:", ssid)

结果一跑,nil,啥也没打印出来。加点打印确认一下:

1
当前 WiFi ssid:    nil

行吧,这条路走不通。

尝试 airport 命令

Mac 上传统获取 WiFi 信息的方式是 airport 命令:

1
2
/usr/local/bin/airport -I
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport

报错了:no such file or directory

查了一下,原来 macOS 新版(Sequoia)把这个 airport 二进制文件移除了。

尝试 networksetup

既然 airport 没了,试一下 networksetup:

1
networksetup -getairportnetwork en0

结果:

1
You are not associated with an AirPort network.

有意思,终端也拿不到 WiFi 信息。说明这事儿不是 hammerspoon 的问题,是系统层面就拿不到。

尝试 system_profiler

1
system_profiler SPAirPortDataType

这个倒是能跑,但是输出里的 SSID 是这样的:

1
"_name" : "<redacted>",

好家伙,给我 redacted 了。

查文档、搜 GitHub

各种搜索尝试,看了 hammerspoon 的 GitHub issues、知乎博客、CSDN 文章… 发现一个问题:大家都在用 hs.wifi.currentNetwork(),但没人提到在新版 macOS 上会返回 nil。

然后突然想到一个关键点:定位权限

新版 macOS 对 WiFi 信息做了隐私保护,需要定位服务权限才能读取。也许 hammerspoon 虽然不需要定位功能本身,但它需要这个权限才能访问 WiFi 信息。

解决方案

在系统设置里开了 Hammerspoon 的定位服务权限。然后在配置里加了一段启用定位服务的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if hs.location.servicesEnabled() then
hs.location.start()

hs.timer.doAfter(2, function()
local location = hs.location.get()
if location then
print("Latitude: " .. (location.latitude or "N/A"))
print("Longitude: " .. (location.longitude or "N/A"))
end
hs.location.stop()
end)
else
print("Location services are not enabled.")
end

reload 配置之后(会自动弹出申请定位权限的确认框),再试 hs.wifi.currentNetwork(),终于拿到 WiFi 名了:ihome.6500.5g

最终代码

既然能拿到 SSID 了,剩下的就简单了:

1
2
3
4
5
6
local ssid = hs.wifi.currentNetwork()
if ssid and string.sub(ssid, 1, 5) == "ihome" then
imagePath = hs.configdir .. "/private/home.png"
else
imagePath = hs.configdir .. "/private/work.png"
end

前缀匹配搞定。

总结

新版 macOS (Sequoia) 对 WiFi 信息做了隐私保护,hs.wifi.currentNetwork() 需要定位权限才能正常返回结果。开启 Hammerspoon 的定位服务权限就好了。

说起来这个问题其实挺好排查的,当初应该先看看系统设置里的权限,而不是在那各种命令行工具来回试。airport 被移除这件事倒是没想到,印象里这玩意儿一直在的,居然也进了苹果的废弃名单。


配置要点

  • 系统设置 → 隐私与安全性 → 定位服务 → Hammerspoon → 开启