Sandboxing coreWLAN?
Я пишу приложение для OS X, которое зависит от способности определять мощность беспроводного сигнала, но я не могу понять, какие права использовать для песочницы.
Всякий раз, когда я использую
NSMutableArray *scanResults;
CWInterface *currentInterface = [CWInterface interface];
NSLog(@"currInterface: %@\n", currentInterface);
NSMutableDictionary *signalsDict = [[NSMutableDictionary alloc] init];
NSError *err = nil;
scanResults = [NSMutableSet setWithSet:[currentInterface scanForNetworksWithSSID:nil error:&err]];
Я получаю ошибку The operation couldn't be completed. (com.apple.coreWLAN.error error 1.)
несмотря на то, что все права проверены в XCode. Какие права я пропускаю?
Пример проекта CoreWLANWirelessManager имеет ту же проблему.
3 ответа
Как насчет прав для приложения Wifi Diagnostics, которое поставляется с Mac OS X 10.11.1, расположенного в /System/Library/CoreServices/Applications/. Проверяя права доступа, я вижу, что он обладает следующим: com.apple.wifi.associate, com.apple.wifi.scan, com.apple.wifi.set_channel, com.apple.wifi.start_autojoin, com.apple.wireless-диагностика, и com.apple.wireless -одиагностика.basic_report.
Разве мы простые смертные, работающие в песочнице, не в состоянии получить их?
Похоже, что CoreWLAN вообще недоступен для изолированных приложений.
Документация разработчика Apple гласит: "С помощью изолированной программной среды приложения ваше приложение не может изменять сетевую конфигурацию системы (будь то с помощью инфраструктуры конфигурации системы, платформы CoreWLAN или других подобных API-интерфейсов)", что, по-видимому, означает, что параметры чтения, но не записи могут быть в порядке, но на практике это не работает, и это подтверждается публикацией Apple DTS: https://forums.developer.apple.com/thread/11307
Возможно, вы захотите использовать частную платформу Apple80211 с помощью библиотеки dlfcn.h. Пример iphone можно найти здесь:
http://www.csse.uwa.edu.au/~chris/iphone/APlogger/
Загрузите исходный файл и исследуйте модуль сканера.
В итоге вы получите что-то вроде этого:
#define IF_NAME "en0"
#include <dlfcn.h>
- (void)performScan
{
int (*open)(void *);
int (*bind)(void *, NSString *);
int (*close)(void *);
int (*scan)(void *, NSArray **, void *);
void *libHandle;
void *airportHandle;
libHandle = dlopen("/System/Library/Frameworks/Preferences.framework/Preferences", RTLD_LAZY);
open = dlsym(libHandle, "Apple80211Open");
bind = dlsym(libHandle, "Apple80211BindToInterface");
scan = dlsym(libHandle, "Apple80211Scan");
close = dlsym(libHandle, "Apple80211Close");
open(&airportHandle);
bind(airportHandle, @IF_NAME);
NSArray *found;
NSDictionary *params = [[NSDictionary alloc] init];
scan(airportHandle, &found, params);
int nnw = [found count];
for(int i=0 ; i < nnw ; i++) {
NSDictionary *nw = [found objectAtIndex:i];
NSString *ssid = [self fixSSID:nw];
// RSSI indicates signal strength
int rssi = [[nw objectForKey:@"RSSI"] intValue];
}
// Cleanup
close(airportHandle);
dlclose(libHandle);
}
-(NSString *)fixSSID:(NSDictionary *)nw
{
if ([[nw objectForKey:@"HIDDEN_NETWORK"] boolValue])
return @"<hidden>";
else
return [nw objectForKey:@"SSID_STR"];
}
Обратите внимание, что если вы используете частные платформы в своих приложениях для iOS, вы не сможете публиковать их в App Store (Apple отклонит ваше приложение, так как нет общедоступной документации для платформы Apple80211). но поскольку ваш вопрос касается разработки OSX, это не относится к вашему делу.
Надеюсь, поможет.
Фарзан Дороудгар