Использование startMonitoringEventWithType: ошибка: при попытке обнаружить изменение SSID Wi-Fi

Похоже, что Apple представила довольно значительные изменения в инфраструктуре Yosemite и CoreWLAN. Я хотел бы использовать его новый API, цитируя заголовочный файл:

/*!
 * @method
 *
 * @param type
 * A CWEventType value.
 *
 * @param error
 * An NSError object passed by reference, which upon return will contain the error if an error occurs.
 * This parameter is optional.
 *
 * @result
 * A BOOL value indicating whether or not an error occurred. YES indicates no error occurred.
 *
 * @abstract 
 * Register for specific Wi-Fi event notifications.
 * 
 * @discussion
 * Requires the <i>com.apple.wifi.events</i> entitlement.
 */
- (BOOL)startMonitoringEventWithType:(CWEventType)type error:(out NSError **)error NS_AVAILABLE_MAC(10_10);

и установка CWEventType в: CWEventTypeSSIDDidChange

Он говорит, что требует прав, но я не могу запустить его на своем Mac. Сообщение об ошибке:

Приложение неожиданно закрылось. Сообщение от отладчика: прекращено из-за ошибки подписи кода.

И мой файл разрешений (где я подозреваю, что проблема) выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.wifi.events</key>
    <true/>
</dict>
</plist>

и я устанавливаю путь подписи кода в настройке сборки для цели. И если говорить о том, что, если я исключаю локальный файл разрешений, приложение запускается, но не работает должным образом. Исследуемый API возвращает объект ошибки со следующим описанием:

Error Domain=com.apple.wifi.request.error Code=4 "The operation couldn’t be completed. (com.apple.wifi.request.error error 4.)"

Это определенно обманщик ума, или, по крайней мере, я надеюсь, что иначе я абсолютный идиот. У меня есть конкретный идентификатор приложения для моего приложения в центре участников, а также определенный профиль разработки (хотя мне это не нужно, так как я использую профиль разработчика с подстановочными знаками).

Заранее спасибо.

2 ответа

Решение

Похоже, что в настоящее время (31 июля 2015 г.) ошибка в CWWiFiClient: права не предоставляются должным образом. Это распространяется даже на приложения без песочницы. См. Этот вопрос на форумах разработчиков Apple для получения дополнительной информации.

В результате нам, возможно, придется прибегнуть к устаревшему API на данный момент. Syammala предоставляет хороший пример того, как использовать устаревший API.

Это делает ту же работу, что вы хотите достичь в выше. Он уведомляет вас при каждом изменении SSID

Чтобы получить эти уведомления, вам нужно держаться за экземпляр CWInterface. Ваш.h будет выглядеть так

#import <Cocoa/Cocoa.h>
@class CWInterface;

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;
@property (retain) CWInterface *wirelessInterface;

@end

Тогда в вашем.m файле будет выглядеть так

#import "AppDelegate.h"
#import <CoreWLAN/CoreWLAN.h>

@implementation AppDelegate

@synthesize window = _window;
@synthesize wirelessInterface;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:CWModeDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:CWSSIDDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:CWBSSIDDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:CWCountryCodeDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:CWLinkDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:CWPowerDidChangeNotification object:nil];

    self.wirelessInterface = [CWInterface interfaceWithName:@"en1"];
}

-(void) handleNotification:(NSNotification*) notification
{
    NSLog(@"Notification Received");
}

@end

Будьте осторожны при использовании имени интерфейса en1 или en0. Проверьте вашу системную систему, посмотрев, к какому интерфейсу подключен ip, предоставив ifconfig

Вы должны использовать CWEventDelegate вместе с startMonitoringEventWithType, в соответствии с документом CWEventDelegate: https://developer.apple.com/documentation/corewlan/cweventdelegate

весь код:

- (void)testDelegateMethod{
    [CWWiFiClient sharedWiFiClient].delegate = self;
    
    NSError *error;
    [[CWWiFiClient sharedWiFiClient] startMonitoringEventWithType:CWEventTypePowerDidChange error:&error];
    [[CWWiFiClient sharedWiFiClient] startMonitoringEventWithType:CWEventTypeSSIDDidChange error:&error];
    [[CWWiFiClient sharedWiFiClient] startMonitoringEventWithType:CWEventTypePowerDidChange error:&error];
    [[CWWiFiClient sharedWiFiClient] startMonitoringEventWithType:CWEventTypeLinkDidChange error:&error];
    [[CWWiFiClient sharedWiFiClient] startMonitoringEventWithType:CWEventTypeNone error:&error];
    
    if (error) {
        NSLog(@"error : %@",error);
    }
}

#pragma mark - CWEventDelegate
- (void)clientConnectionInterrupted{
    NSLog(@"-- clientConnectionInterrupted");
}

- (void)clientConnectionInvalidated{
    
    NSLog(@"-- clientConnectionInvalidated");
}


- (void)powerStateDidChangeForWiFiInterfaceWithName:(NSString *)interfaceName{
    NSLog(@"-- %@ powerStateDidChange  ",interfaceName);
}

- (void)ssidDidChangeForWiFiInterfaceWithName:(NSString *)interfaceName{
    NSLog(@"-- %@ ssidDidChange",interfaceName);
}

Другие вопросы по тегам