如何使用私有 API 检测 iOS 中任何已启用的热点

问题描述 投票:0回答:1

我想检测用户是否在 iOS 设备上启用了热点/网络共享。我可以使用私有 API,但知道它不会进入应用商店。

我试图浏览私有 API 列表/运行时标头,但有太多无法决定哪个可能有帮助。我正在尝试找到

UIApplicationWillChangeStatusBarFrameNotification
在私有 API 中被触发的位置(可能是为了主动调用和激活热点等而调用的)

我尝试了检测个人热点并且也使用了CaptiveNetwork,但它只返回连接的WiFi SSID,而不返回创建的热点。

使用上面的代码,编译器显示错误

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 的字典。

通过像这样更改文件,除了我们知道此代码不会进入应用程序商店这一事实之外,我在存档构建时还会遇到任何问题(或任何其他问题)吗?

ios wifi iphone-privateapi hotspot tethering
1个回答
10
投票

没有私有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

© www.soinside.com 2019 - 2024. All rights reserved.