在OSX App中显示已知Wifi网络列表所需的钥匙串访问

时间:2011-02-02 00:04:59

标签: cocoa macos

我的OSX应用程序需要显示用户已知的wifi网络列表。我已经知道如何使用CoreWLAN框架执行此操作。我正在使用的代码是:

CWInterface *interface = [[CWInterface alloc] init];
NSArray *knownNetworks = interface.configuration.preferredNetworks;

这很好用,除了当我这样做时,OSX会提示用户说我的应用程序需要存储密码短语的每个网络的密钥链访问权限。 “preferredNetworks”属性返回CWWirelessProfile对象的数组。这个类的一个属性是“密码”。我相信这个属性是我的应用程序需要访问钥匙串的原因。

我不需要甚至不想要用户已知网络的密码短语。我所关心的只是SSID。有没有办法在不提取密码的情况下查询已知SSID列表?如果我的应用没有提示用户需要密钥链访问,我更喜欢它。此外,在我的情况下,提示无用,因为无论用户是否点击“允许”或“拒绝”,我仍然可以访问网络的SSID。

2 个答案:

答案 0 :(得分:1)

事实证明,巴伐利亚是正确的;我可以利用系统配置框架来检索已知的wifi网络列表,而不会提示用户进行管理员访问。这是我最终创建的类来处理这个:

static NSString *configPath = @"/Library/Preferences/SystemConfiguration/preferences.plist";

@implementation KnownWifiNetworks

/**
 This method reads the SystemConfiguration file located at configPath. Its schema is described in Apple's
 Documentation at this url:
 http://developer.apple.com/library/mac/#documentation/Networking/Conceptual/SystemConfigFrameworks/SC_Components/SC_Components.html

 TODO: Cache the results so we don't have the read the file every time?
 */
+ (NSArray *)allKnownNetworks {
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:50];
    @try {
        NSDictionary *config = [NSDictionary dictionaryWithContentsOfFile:configPath];
        NSDictionary *sets = [config objectForKey:@"Sets"];
        for (NSString *setKey in sets) {
            NSDictionary *set = [sets objectForKey:setKey];
            NSDictionary *network = [set objectForKey:@"Network"];
            NSDictionary *interface = [network objectForKey:@"Interface"];
            for(NSString *interfaceKey in interface) {
                NSDictionary *bsdInterface = [interface objectForKey:interfaceKey];
                for(NSString *namedInterfaceKey in bsdInterface) {
                    NSDictionary *namedInterface = [bsdInterface objectForKey:namedInterfaceKey];
                    NSArray *networks = [namedInterface objectForKey:@"PreferredNetworks"];
                    for (NSDictionary *network in networks) {
                        NSString *ssid = [network objectForKey:@"SSID_STR"];
                        [result addObject:ssid];
                    }
                }
            }
        }
    } @catch (NSException * e) {
        NSLog(@"Failed to read known networks: %@", e);
    }
    return result;
}

@end

答案 1 :(得分:1)

我已经能够使用CoreWLAN框架类来获取已知网络SSID的列表,而无需像以下那样访问密钥链:

NSMutableArray *result = [NSMutableArray arrayWithCapacity:50];
CWInterface *interface = [CWInterface interface];
NSEnumerator *profiles = [interface.configuration.networkProfiles objectEnumerator];
CWNetworkProfile *profile;
while (profile = [profiles nextObject]) {
    [result addObject:profile.ssid];
}
return result;

似乎不推荐使用CWInterface.configuration.preferredNetworks,但此解决方案运行良好。