使用私有 api 检测 iOS 中启用的热点

Posted

技术标签:

【中文标题】使用私有 api 检测 iOS 中启用的热点【英文标题】:detect hotspot enabling in iOS with private api's 【发布时间】:2015-07-04 11:58:44 【问题描述】:

好的,所以我想检测用户是否在 ios 设备中启用了热点/网络共享。我可以使用私有 api,知道它不会进入应用商店。

我正在尝试通过private api's list/ runtime headers,但有太多无法决定哪个可能有帮助。

或者我是否可以知道 UIApplicationWillChangeStatusBarFrameNotification 在私有 api 中被触发的位置(可能会调用主动调用和激活热点等)

我试过这个detect personal hotspot 并且也使用了 CaptiveNetwork,但它只返回连接的 wi-fi ssid 而不是创建的热点。

分享的任何知识都将非常有帮助

更新:@creker

使用上面的代码,编译器显示错误“ SCDynamicStoreCreate 不可用:在 iOS 上不可用。所以我进入 SCDynamicStore.h 并更改了以下内容

    SCDynamicStoreRef
SCDynamicStoreCreate            (
                    CFAllocatorRef          allocator,
                    CFStringRef         name,
                    SCDynamicStoreCallBack      callout,
                    SCDynamicStoreContext       *context
                    )               __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA);

    SCDynamicStoreRef
SCDynamicStoreCreate            (
                    CFAllocatorRef          allocator,
                    CFStringRef         name,
                    SCDynamicStoreCallBack      callout,
                    SCDynamicStoreContext       *context
                    )               __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_6_0);

现在我能够获得状态为 1022 和 1023 的字典。只是想通过更改这样的文件来确认(以前没有做过)我在归档构建(或任何其他问题)时会遇到任何问题(或任何其他问题)事实上我们知道这段代码不会进入应用商店

【问题讨论】:

【参考方案1】:

没有私有 API

您可以通过使用 C API 枚举网络接口来检测活动的个人热点。当热点处于活动状态并且有人连接到它时,将出现带有bridge 前缀的接口。在我的 iPhone 5 上是bridge100。如果热点被禁用或没有人连接到它,则该接口甚至不会出现在列表中。

C API 甚至会返回该网络中的 IP 地址和子网掩码。

这就是我在应用程序中用来检测活动热点的方法。

要获得 SSID,您需要 [[UIDevice currentDevice] name] - 个人热点 SSID 始终与设备名称匹配。

使用私有 API

您可以使用此代码获取有关个人热点的所有信息:

SCDynamicStoreRef sc = SCDynamicStoreCreate(NULL, CFSTR("com.apple.wirelessmodemsettings.MISManager"), NULL, NULL);
NSDictionary* info = (__bridge_transfer NSDictionary*)SCDynamicStoreCopyValue(sc, CFSTR("com.apple.MobileInternetSharing"));
CFRelease(sc);

info 字典在热点处于活动状态且有连接时将如下所示:


    Errnum = 0;
    ExternalInterfaces =     (
        "pdp_ip0"
    );
    Hosts =     
        Current = 1;
        Max = 5;
        MoreAllowed = 1;
        Type =         
            AirPort = 0;
            Bluetooth = 0;
            Ethernet = 0;
            "USB-Ethernet" = 1;
        ;
    ;
    InternalInterfaces =     (
        bridge100
    );
    Reason = 0;
    State = 1023;
    Version = 2;
 

当热点处于活动状态但没有连接时:


    Errnum = 0;
    ExternalInterfaces =     (
    );
    Hosts =     
        Current = 0;
        Max = 5;
        MoreAllowed = 1;
        Type =         
            AirPort = 0;
            Bluetooth = 0;
            Ethernet = 0;
            "USB-Ethernet" = 0;
        ;
    ;
    InternalInterfaces =     (
    );
    Reason = 0;
    State = 1023;
    Version = 2;

热点未激活时:


    Errnum = 45;
    ExternalInterfaces =     (
    );
    Hosts =     
        Current = 0;
        Max = 5;
        MoreAllowed = 1;
        Type =         
            AirPort = 0;
            Bluetooth = 0;
            Ethernet = 0;
            "USB-Ethernet" = 0;
        ;
    ;
    InternalInterfaces =     (
    );
    Reason = 0;
    State = 1022;
    Version = 2;

当热点处于活动状态时,State 密钥将等于 1023,无论活动连接如何。我不知道该值是否包含位标志。 iOS 实际上是在检查值是否等于1023

SCDynamicStore API 来自公共 SystemConfiguration 框架,但在 iOS 平台上标记为不可用。这意味着所有标题都在那里,您只需要复制没有__OSX_AVAILABLE_STARTING 宏的定义。

您甚至可以观察对该设置的更改 - 您可以指定要观察哪个值的键。阅读 Apple 文档了解实现细节。

更新

所以我进入 SCDynamicStore.h 并更改了以下内容

我不会那样做。它不应该引起任何问题,但对我来说更改 SDK 标头不是一个好的解决方案。我建议以下。不要包含框架标题。创建您自己的标题,在其中复制您需要的所有方法,并更改或删除__OSX_AVAILABLE_STARTING

【讨论】:

这与 OP 的“检测个人热点”链接有何不同? @JesseRusak,我对他的问题给出了完整的回答,包括热点的 SSID。链接中的代码使用了错误的接口名称。如您所见,寻找bridge0 是错误的——在较新的设备上它被称为bridge100。我们只需要查找前缀bridge 太棒了。有效。到目前为止,我也得到了 bridge100。但我仍然想知道是否可以让热点处于活动状态,而不管没有人连接到该热点吗? @creker 我已经更新了这个问题,有另一个问题希望我们可以关闭它 您好,我尝试使用您的代码获取热点信息。但我得到以下错误。 'SCDynamicStoreCreate' 不可用:在 iOS 上不可用。 'SCDynamicStoreCopyValue' 下面的其他错误不可用:在 iOS 上不可用。有什么方法可以解决上述问题吗?我在 xcode6.4.iOS SDK 8.4 中尝试这些代码。非常感谢。

以上是关于使用私有 api 检测 iOS 中启用的热点的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在iPhone中以编程方式启用热点模式?

iOS : Homekit - 如何检测设备中是不是启用蓝牙和 WiFi 服务?

如何在私有模式下在 iOS Safari 浏览器上启用 LocalStorage?

如何检测我的 iOS 应用已启用 PIE/ASLR?

如何检测在 iOS 8 上包含应用程序时启用了应用程序扩展?

检测 OS X 上的 iCloud 可用性变化