using startMonitoringEventWithType: error: in the effort to detect wifi SSID change
Asked Answered
H

3

12

Apple seems to introduce quite a change with Yosemite and CoreWLAN framework. I would like to use its new API, quoting the header file:

/*!
 * @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);

and setting CWEventType to: CWEventTypeSSIDDidChange

It says it requires entitlement, but I am not being able to run it on my mac. The error message is:

The app quit unexpectedly. Message from debugger: Terminated due to code signing error.

And my entitlements file (where I suspect the problem to be) is like this:

<?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>

and I am setting the code signing path in the build setting for the target. And speaking of which, if I exclude the local entitlements file, the app runs but doesn't behave as expected. The API under study returns an error object with following description:

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

It is definitely a mind twister, or at least I hope it is otherwise I am a total idiot. I have a specific App ID for my app in the member center, as well as a specific development profile (although I shouldn't have to since I am using a wildcard dev profile).

Thanks in advance.

Heptateuch answered 15/12, 2014 at 23:43 Comment(3)
CWWiFiClient appears to have issues: forums.developer.apple.com/thread/11307 May have to resort to the deprecated API for now :(Collocutor
Thanks @jvmk for this link. Maybe you should consider posting it as an answer.Heptateuch
followed your advice and posted an answer. I was refraining from posting it as an answer at first as it will not have any long-term value, i.e. hopefully the bug will be fixed soon :).Collocutor
C
4

It seems that there is currently (31st of July 2015) a bug in CWWiFiClient: entitlements are not properly granted. This even extends to non-sandboxed apps. See this question on the Apple developer forums for more information.

As a result, we may have to resort to the deprecated API for the time being. syammala provides a good example of how to use the deprecated API.

Collocutor answered 31/7, 2015 at 22:1 Comment(0)
I
3

This does the same job what you want to achieve in above. It notifies you whenever SSID changes

In order for you to get those notifications you need to be holding on to an instance of CWInterface. Your .h would look like this

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

@interface AppDelegate : NSObject <NSApplicationDelegate>

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

@end

Then in your .m file would look like this

#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

Take care while using interface name en1 or en0. Check your sysytem by seeing to which interface ip is present by giving ifconfig

Immensurable answered 22/5, 2015 at 5:18 Comment(3)
Thanks @syammala for the answer. These notifications are deprecated in OS X 10.10. I am looking to use the new API which is suggested in the deprecation note in Xcode. I remember facing this issue on 10.10.1, I haven't checked if 10.10.3 did include a fix for this but I think it does.Heptateuch
No @syammala your answer did not help. My question was regarding a specific API. Please take another look at the title. Also, in the first sentence in the question's body, I was clear and said: "I want to use the new API".Heptateuch
I get the same problem on 10.10.3. Code signing error when I add com.apple.wifi.events to entitlements and CWSSIDDidChangeNotification now deprecated...Krell
C
2

you should use CWEventDelegate together with startMonitoringEventWithType, according to the document of CWEventDelegate: https://developer.apple.com/documentation/corewlan/cweventdelegate

the whole code is :

- (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);
}
Criminal answered 5/12, 2018 at 9:23 Comment(1)
Thanks @melissa. I am no longer working on that project, but I think it is great that you added this updated answer. I hope this info will be helpful for someone else.Heptateuch

© 2022 - 2024 — McMap. All rights reserved.