使用私有 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 中启用的热点的主要内容,如果未能解决你的问题,请参考以下文章
iOS : Homekit - 如何检测设备中是不是启用蓝牙和 WiFi 服务?
如何在私有模式下在 iOS Safari 浏览器上启用 LocalStorage?