使用私有api

时间:2015-07-04 11:58:45

标签: ios iphone-privateapi tethering personal-hotspot

好的,所以我想检测一下用户在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 个答案:

答案 0 :(得分:10)

没有私有API

您可以通过使用C API枚举网络接口来检测活动的个人热点。当hotpost处于活动状态且有人连接到它时,将会有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的情况下复制所需的所有方法,制作自己的标题。