11

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.)"

这绝对是一个头脑扭曲,或者至少我希望不是这样,否则我就是个白痴。我在会员中心有我的应用程序的特定应用程序 ID,以及特定的开发配置文件(尽管我不应该这样做,因为我使用的是通配符开发配置文件)。

提前致谢。

4

3 回答 3

4

目前(2015 年 7 月 31 日)似乎存在一个错误CWWiFiClient:未正确授予权利。这甚至扩展到非沙盒应用程序。有关更多信息,请参阅Apple 开发者论坛上的此问题。

因此,我们可能暂时不得不求助于已弃用的 API。syammala 提供了一个很好的示例来说明如何使用已弃用的 API。

于 2015-07-31T22:01:56.027 回答
3

这与您在上面想要实现的工作相同。它会在 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 时要小心。通过提供 ifconfig 查看存在的接口 ip 检查您的系统

于 2015-05-22T05:18:58.280 回答
2

您应该将 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);
}

于 2018-12-05T09:23:22.730 回答