【问题标题】:using startMonitoringEventWithType: error: in the effort to detect wifi SSID change使用 startMonitoringEventWithType: 错误:努力检测 wifi SSID 变化
【发布时间】:2015-02-14 05:01:06
【问题描述】:

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

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

提前致谢。

【问题讨论】:

  • CWWiFiClient 似乎有问题:forums.developer.apple.com/thread/11307 现在可能不得不求助于已弃用的 API :(
  • 感谢@jvmk 提供此链接。也许您应该考虑将其发布为答案。
  • 听从了您的建议并发布了答案。起初我没有将其发布为答案,因为它没有任何长期价值,即希望该错误将很快得到修复:)。

标签: macos cocoa osx-yosemite ssid corewlan


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    这与您在上面想要实现的工作相同。它会在 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 来检查您的系统

    【讨论】:

    • 感谢@syammala 的回答。这些通知在 OS X 10.10 中已弃用。我希望使用 Xcode 的弃用说明中建议的新 API。我记得在 10.10.1 上遇到过这个问题,我没有检查 10.10.3 是否包含对此的修复,但我认为它确实包含。
    • 否 @syammala 您的回答没有帮助。我的问题是关于一个特定的 API。请再看一下标题。此外,在问题正文的第一句话中,我明确表示:“我想使用新的 API”。
    • 我在 10.10.3 上遇到了同样的问题。当我将 com.apple.wifi.events 添加到权利和 CWSSIDDidChangeNotification 现在已弃用时出现代码签名错误...
    【解决方案3】:

    你应该和startMonitoringEventWithType一起使用CWEventDelegate,根据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);
    }

    【讨论】:

    • 谢谢@melissa。我不再从事该项目,但我认为您添加了这个更新的答案真是太好了。我希望这些信息对其他人有所帮助。
    猜你喜欢
    • 2016-10-08
    • 2014-01-05
    • 2016-04-27
    • 1970-01-01
    • 2015-01-20
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多