我试图在Mac OS上使用SystemConfiguration来在Mac上出现新的网络接口并为其分配新的IP地址时获得通知。
我将其设置为监视系统配置密钥State:/Network/Interface
,并且当出现新的网络接口时,我都会收到通知。
但是,只要在新网络接口上分配了IPv4地址(例如通过DHCP),我都希望收到通知。我知道键State:/Network/Interface/en0/IPv4
拥有en0接口的IPv4地址。但是,对于所有IPv4地址State:/Network/Interface/.*/IPv4
使用手册页中描述的正则表达式不适用于新接口。
我在github上整理了一个很小的最小代码示例,但是也可以使用scutil
命令行工具。
main.c
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
/* Callback used if a configuration change on monitored keys was detected.
*/
void dynamicStoreCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void* __nullable info) {
CFIndex count = CFArrayGetCount(changedKeys);
for (CFIndex i=0; i<count; i++) {
NSLog(@"Key \"%@\" was changed", CFArrayGetValueAtIndex(changedKeys, i));
}
}
int main(int argc, const char * argv[]) {
NSArray *SCMonitoringInterfaceKeys = @[@"State:/Network/Interface.*"];
@autoreleasepool {
SCDynamicStoreRef dsr = SCDynamicStoreCreate(NULL, CFSTR("network_interface_detector"), &dynamicStoreCallback, NULL);
SCDynamicStoreSetNotificationKeys(dsr, CFBridgingRetain(SCMonitoringInterfaceKeys), NULL);
CFRunLoopAddSource(CFRunLoopGetCurrent(), SCDynamicStoreCreateRunLoopSource(NULL, dsr, 0), kCFRunLoopDefaultMode);
NSLog(@"Starting RunLoop...");
while([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
}
return 0;
}
答案 0 :(得分:0)
在一些开发人员同事的帮助下,我找出了问题所在。 SCDynamicStoreSetNotificationKeys
函数的签名如下:
Boolean SCDynamicStoreSetNotificationKeys (SCDynamicStoreRef store,
CFArrayRef __nullable keys,
CFArrayRef __nullable patterns
)
这意味着我必须与用作树根的键分开设置模式,在树的根下将进行模式匹配。这是我的 main.m 的修改版本:
int main(int argc, const char * argv[]) {
NSArray *SCMonitoringInterfaceKeys = @[@"State:/Network/Interface"];
NSArray *patterns = @[@"en\\d*/IPv4"];
@autoreleasepool {
SCDynamicStoreRef dsr = SCDynamicStoreCreate(NULL, CFSTR("network_interface_detector"), &dynamicStoreCallback, NULL);
SCDynamicStoreSetNotificationKeys(dsr, CFBridgingRetain(SCMonitoringInterfaceKeys), CFBridgingRetain(patterns));
CFRunLoopAddSource(CFRunLoopGetCurrent(), SCDynamicStoreCreateRunLoopSource(NULL, dsr, 0), kCFRunLoopDefaultMode);
NSLog(@"Starting RunLoop...");
while([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
}
return 0;
}
我已经包含了解决方案into the solved branch of the repo。