используя 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.)"

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

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


person Muhammad Arafat    schedule 15.12.2014    source источник
comment
CWWiFiClient имеет проблемы: forums.developer.apple.com/thread/11307 May пока приходится прибегать к устаревшему API :(   -  person Janus Varmarken    schedule 30.07.2015
comment
Спасибо @jvmk за эту ссылку. Возможно, вам следует рассмотреть возможность публикации его в качестве ответа.   -  person Muhammad Arafat    schedule 31.07.2015
comment
последовал твоему совету и написал ответ. Сначала я воздерживался от публикации его в качестве ответа, так как он не будет иметь долгосрочной ценности, т.е. надеюсь, что ошибка скоро будет исправлена ​​:).   -  person Janus Varmarken    schedule 01.08.2015


Ответы (3)


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

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

person Janus Varmarken    schedule 31.07.2015

Это делает ту же работу, которую вы хотите достичь выше. Он уведомляет вас всякий раз, когда меняется 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

person MacDeveloper    schedule 22.05.2015
comment
Спасибо @syammala за ответ. Эти уведомления устарели в OS X 10.10. Я хочу использовать новый API, который предлагается в примечании об устаревании в Xcode. Я помню, как столкнулся с этой проблемой в 10.10.1, я не проверял, включает ли 10.10.3 исправление для этого, но я думаю, что оно есть. - person Muhammad Arafat; 23.05.2015
comment
Нет, @syammala, твой ответ не помог. Мой вопрос касался конкретного API. Пожалуйста, взгляните еще раз на заголовок. Кроме того, в первом предложении в теле вопроса я ясно сказал: я хочу использовать новый API. - person Muhammad Arafat; 01.06.2015
comment
У меня такая же проблема на 10.10.3. Ошибка подписи кода, когда я добавляю com.apple.wifi.events в права, а CWSSIDDidChangeNotification теперь устарел... - person user1024447; 27.06.2015

вы должны использовать 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);
}

person Shu Shu    schedule 05.12.2018
comment
Спасибо @melissa. Я больше не работаю над этим проектом, но я думаю, что здорово, что вы добавили этот обновленный ответ. Я надеюсь, что эта информация будет полезна для кого-то еще. - person Muhammad Arafat; 06.12.2018