这是针对调整,因此目标是越狱设备,不应用商店。
我曾尝试在SBWiFiManager
中挂钩不同的方法,但是当wifi强度发生变化(如此连续)或者在网络发生变化后相当延迟之后,它们会被调用。
有没有其他方法可以获得通知(或其他方法来挂钩)wifi网络的变化?
我知道您现在可以使用公共API获取当前的SSID,但我需要告知它何时更改。
答案 0 :(得分:16)
执行此操作的一种方法是从Core Foundation Darwin通知中心收听com.apple.system.config.network_change
事件。
注册活动:
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);
}
}
例如,请参阅my link to another answer有关如何使用强制网络API获取当前SSID的信息。
请注意,虽然我测试过的手机是越狱(iOS 6.1),但我认为这不需要越狱才能正常工作。它当然不需要将应用程序安装在正常的沙箱区域(/var/mobile/Applications/*
)之外。
P.S。我没有详尽地测试这个,以了解此事件是否给出任何误报(基于您对网络更改的定义)。但是,只要存储一些状态变量(等于最后一个网络的SSID),并且只要该事件发生,就将其与当前变量进行比较,这很简单。
答案 1 :(得分:1)
SWIFT 4.1版
我用这个函数扩展了我的Reachability类:
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。 希望这对某些人有帮助)