ios - 使用私有(private) api 在 iOS 中检测启用的热点

标签 ios iphone-privateapi tethering personal-hotspot

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

我试图通过private api's list/ runtime headers但太多了,无法决定哪些可能有用。

或者如果我能知道 UIApplicationWillChangeStatusBarFrameNotification 在私有(private) 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 的字典。只是想通过像这样更改文件(以前没有做过)来确认我在归档构建时是否有任何问题(或任何其他问题),除了事实上,我们知道这段代码不会进入应用商店

最佳答案

没有私有(private) API

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

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

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

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

使用私有(private) 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 来自公共(public) SystemConfiguration 框架,但标记为在 iOS 平台上不可用。这意味着所有 header 都在那里,您只需要复制没有 __OSX_AVAILABLE_STARTING 宏的定义。

您甚至可以观察到该设置的变化 - 您可以指定一个键来观察哪个值。阅读 Apple 文档以了解实现细节。

更新

So i went into SCDynamicStore.h and changed the following

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

关于ios - 使用私有(private) api 在 iOS 中检测启用的热点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31220371/

相关文章:

ios uinavigationcontroller 到 uiviewcontroller

ios - 来自 Web 服务器的音频和视频流

ios - 理论/标志 : Accessing Static/Global Variable Across Multiple Hooked Processes

iphone - 我的项目中使用的私有(private) API - 初学者

android - 在 Android-x86 上网本上使用 ADB over Bluetooth 调试应用程序

ios - 复杂图像(气泡/图钉)和 [UIImage ressizedImageWithCapInsets :]

ios - Swift 2 的错误处理

ios - 如何抑制 "Availability does not match previous declaration"警告

android - 以编程方式启用 USB Tethering Android,无需用户交互

通过蓝牙 PAN 在 MacBook Air 上进行 Android 4.4.2 反向网络共享 - 未连接到互联网