这是一个调整,所以目标是越狱设备,而不是应用商店。我曾尝试在其中挂钩不同的方法,SBWiFiManager
但它们要么在 wifi 强度变化(如此连续)时被调用,要么在网络变化后相当延迟后被调用。
有没有其他方法可以获取通知(或其他方法来挂钩)wifi 网络更改?
我知道您现在可以通过公共 API 获取当前的 SSID,但是当它发生变化时需要告知我。
一种方法是com.apple.system.config.network_change
从 Core Foundation Darwin 通知中心监听事件。
报名参加活动:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
NULL, // observer
onNotifyCallback, // callback
CFSTR("com.apple.system.config.network_change"), // event name
NULL, // object
CFNotificationSuspensionBehaviorDeliverImmediately);
这是一个示例回调:
static void onNotifyCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
NSString* notifyName = (NSString*)name;
// this check should really only be necessary if you reuse this one callback method
// for multiple Darwin notification events
if ([notifyName isEqualToString:@"com.apple.system.config.network_change"]) {
// use the Captive Network API to get more information at this point
// https://stackoverflow.com/a/4714842/119114
} else {
NSLog(@"intercepted %@", notifyName);
}
}
例如,请参阅我对如何使用 Captive Network API 获取当前 SSID 的另一个答案的链接。
请注意,虽然我测试过的手机已经越狱(iOS 6.1),但我认为这不需要越狱才能正常工作。它当然不需要将应用程序安装在普通沙盒区域之外 ( /var/mobile/Applications/*
)。
PS我没有对此进行足够详尽的测试,无法知道此事件是否会产生任何误报(基于您对网络更改的定义)。然而,只要存储一些状态变量就足够简单了,等于最后一个网络的 SSID,并在此事件发生时将其与当前的 SSID 进行比较。
SWIFT 4.1 版本
我用这个函数扩展了我的可达性类:
let notificationName = "com.apple.system.config.network_change"
func onNetworkChange(_ name : String) {
if (name == notificationName) {
// Do your stuff
print("Network was changed")
}
}
func registerObserver() {
let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer,
{ (nc, observer, name, _, _) -> Swift.Void in
if let observer = observer, let name = name {
let instance = Unmanaged<Reachability>.fromOpaque(observer).takeUnretainedValue()
instance.onNetworkChange(name.rawValue as String)
} },
notificationName as CFString, nil, .deliverImmediately)
}
func removeObserver() {
let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), observer, nil, nil)
}
在 init 上注册观察者并在 deinit 上删除。不幸的是,没有关于具体更改内容的其他信息,但我们有机会测试当前的 SSID。希望这对某人有帮助)