ios iPhone在没有私人图书馆的情况下获得SSID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5198716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iPhone get SSID without private library
提问by Steve Reed Sr
I have a commercial app that has a completely legitimate reason to see the SSID of the network it is connected to: If it is connected to a Adhoc network for a 3rd party hardware device it needs to be functioning in a different manner than if it is connected to the internet.
我有一个商业应用程序,它有一个完全合法的理由来查看它所连接的网络的 SSID:如果它连接到第三方硬件设备的 Adhoc 网络,它需要以与它不同的方式运行连接到互联网。
Everything I've seen about getting the SSID tells me I have to use Apple80211, which I understand is a private library. I also read that if I use a private library Apple will not approve the app.
我所看到的有关获取 SSID 的所有信息都告诉我,我必须使用 Apple80211,据我所知,这是一个私人图书馆。我还读到,如果我使用私人图书馆,Apple 将不会批准该应用程序。
Am I stuck between an Apple and a hard place, or is there something I'm missing here?
我是否被困在 Apple 和一个艰难的地方之间,还是我在这里遗漏了什么?
回答by Jeremy W. Sherman
As of iOS 7 or 8, you can do this (need Entitlement for iOS 12+ as shown below):
从 iOS 7 或 8 开始,您可以执行此操作(需要 iOS 12+ 的权利,如下所示):
@import SystemConfiguration.CaptiveNetwork;
/** Returns first non-empty SSID network info dictionary.
* @see CNCopyCurrentNetworkInfo */
- (NSDictionary *)fetchSSIDInfo {
NSArray *interfaceNames = CFBridgingRelease(CNCopySupportedInterfaces());
NSLog(@"%s: Supported interfaces: %@", __func__, interfaceNames);
NSDictionary *SSIDInfo;
for (NSString *interfaceName in interfaceNames) {
SSIDInfo = CFBridgingRelease(
CNCopyCurrentNetworkInfo((__bridge CFStringRef)interfaceName));
NSLog(@"%s: %@ => %@", __func__, interfaceName, SSIDInfo);
BOOL isNotEmpty = (SSIDInfo.count > 0);
if (isNotEmpty) {
break;
}
}
return SSIDInfo;
}
Example output:
示例输出:
2011-03-04 15:32:00.669 ShowSSID[4857:307] -[ShowSSIDAppDelegate fetchSSIDInfo]: Supported interfaces: (
en0
)
2011-03-04 15:32:00.693 ShowSSID[4857:307] -[ShowSSIDAppDelegate fetchSSIDInfo]: en0 => {
BSSID = "ca:fe:ca:fe:ca:fe";
SSID = XXXX;
SSIDDATA = <01234567 01234567 01234567>;
}
Note that no ifs are supported on the simulator. Test on your device.
请注意,模拟器不支持 ifs。在您的设备上进行测试。
iOS 12
iOS 12
You must enable access wifi info from capabilities.
您必须从功能中启用访问 wifi 信息。
Important To use this function in iOS 12 and later, enable the Access WiFi Information capability for your app in Xcode. When you enable this capability, Xcode automatically adds the Access WiFi Information entitlement to your entitlements file and App ID. Documentation link
重要要在 iOS 12 及更高版本中使用此功能,请在 Xcode 中为您的应用启用访问 WiFi 信息功能。当您启用此功能时,Xcode 会自动将 Access WiFi Information 权利添加到您的权利文件和 App ID。文档链接
Swift 4.2
斯威夫特 4.2
func getConnectedWifiInfo() -> [AnyHashable: Any]? {
if let ifs = CFBridgingRetain( CNCopySupportedInterfaces()) as? [String],
let ifName = ifs.first as CFString?,
let info = CFBridgingRetain( CNCopyCurrentNetworkInfo((ifName))) as? [AnyHashable: Any] {
return info
}
return nil
}
回答by esad
Here's the cleaned up ARC version, based on @elsurudo's code:
这是基于@elsurudo 代码的清理后的 ARC 版本:
- (id)fetchSSIDInfo {
NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
NSLog(@"Supported interfaces: %@", ifs);
NSDictionary *info;
for (NSString *ifnam in ifs) {
info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
NSLog(@"%@ => %@", ifnam, info);
if (info && [info count]) { break; }
}
return info;
}
回答by Emin Israfil iOS
UPDATE FOR iOS 10 and up
iOS 10 及更高版本的更新
CNCopySupportedInterfaces is no longer deprecated in iOS 10. (API Reference)
CNCopySupportedInterfaces 在 iOS 10 中不再被弃用。(API 参考)
You need to import SystemConfiguration/CaptiveNetwork.hand add SystemConfiguration.frameworkto your target's Linked Libraries (under build phases).
您需要导入SystemConfiguration/CaptiveNetwork.h并将SystemConfiguration.framework添加到目标的链接库(在构建阶段)。
Here is a code snippet in swift (RikiRiocma's Answer):
这是 swift 中的代码片段(RikiRiocma 的回答):
import Foundation
import SystemConfiguration.CaptiveNetwork
public class SSID {
class func fetchSSIDInfo() -> String {
var currentSSID = ""
if let interfaces = CNCopySupportedInterfaces() {
for i in 0..<CFArrayGetCount(interfaces) {
let interfaceName: UnsafePointer<Void> = CFArrayGetValueAtIndex(interfaces, i)
let rec = unsafeBitCast(interfaceName, AnyObject.self)
let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)")
if unsafeInterfaceData != nil {
let interfaceData = unsafeInterfaceData! as Dictionary!
currentSSID = interfaceData["SSID"] as! String
}
}
}
return currentSSID
}
}
(Important:CNCopySupportedInterfaces returns nil on simulator.)
(重要提示:CNCopySupportedInterfaces 在模拟器上返回 nil。)
For Objective-c, see Esad's answer here and below
对于 Objective-c,请参阅此处和下方 Esad 的回答
+ (NSString *)GetCurrentWifiHotSpotName {
NSString *wifiName = nil;
NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
for (NSString *ifnam in ifs) {
NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
if (info[@"SSID"]) {
wifiName = info[@"SSID"];
}
}
return wifiName;
}
UPDATE FOR iOS 9
iOS 9 更新
As of iOS 9 Captive Network is deprecated*. (source)
自 iOS 9 起,Captive Network 已弃用*。(来源)
*No longer deprecated in iOS 10, see above.
*不再在 iOS 10 中弃用,见上文。
It's recommended you use NEHotspotHelper (source)
建议您使用 NEHotspotHelper(来源)
You will need to email apple at [email protected] and request entitlements. (source)
您需要发送电子邮件至 [email protected] 并请求授权。(来源)
Sample Code (Not my code. See Pablo A's answer):
示例代码(不是我的代码。请参阅 Pablo A 的回答):
for(NEHotspotNetwork *hotspotNetwork in [NEHotspotHelper supportedNetworkInterfaces]) {
NSString *ssid = hotspotNetwork.SSID;
NSString *bssid = hotspotNetwork.BSSID;
BOOL secure = hotspotNetwork.secure;
BOOL autoJoined = hotspotNetwork.autoJoined;
double signalStrength = hotspotNetwork.signalStrength;
}
Side note: Yup, they deprecated CNCopySupportedInterfaces in iOS 9 and reversed their position in iOS 10. I spoke with an Apple networking engineer and the reversal came after so many people filed Radars and spoke out about the issue on the Apple Developer forums.
旁注:是的,他们在 iOS 9 中弃用了 CNCopySupportedInterfaces 并在 iOS 10 中改变了他们的立场。我与一位 Apple 网络工程师进行了交谈,在如此多的人提交 Radars 并在 Apple 开发者论坛上谈论这个问题之后发生了逆转。
回答by Chris
This works for me on the device (not simulator). Make sure you add the systemconfiguration framework.
这适用于我的设备(不是模拟器)。确保添加系统配置框架。
#import <SystemConfiguration/CaptiveNetwork.h>
+ (NSString *)currentWifiSSID {
// Does not work on the simulator.
NSString *ssid = nil;
NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
for (NSString *ifnam in ifs) {
NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
if (info[@"SSID"]) {
ssid = info[@"SSID"];
}
}
return ssid;
}
回答by Jameel
This code work well in order to get SSID.
这段代码可以很好地获取 SSID。
#import <SystemConfiguration/CaptiveNetwork.h>
@implementation IODAppDelegate
@synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CFArrayRef myArray = CNCopySupportedInterfaces();
CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));
NSLog(@"Connected at:%@",myDict);
NSDictionary *myDictionary = (__bridge_transfer NSDictionary*)myDict;
NSString * BSSID = [myDictionary objectForKey:@"BSSID"];
NSLog(@"bssid is %@",BSSID);
// Override point for customization after application launch.
return YES;
}
And this is the results :
这是结果:
Connected at:{
BSSID = 0;
SSID = "Eqra'aOrange";
SSIDDATA = <45717261 27614f72 616e6765>;
}
}
回答by Muvimotv
If you are running iOS 12 you will need to do an extra step. I've been struggling to make this code work and finally found this on Apple's site: "Important To use this function in iOS 12 and later, enable the Access WiFi Information capability for your app in Xcode. When you enable this capability, Xcode automatically adds the Access WiFi Information entitlement to your entitlements file and App ID." https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo
如果您运行的是 iOS 12,则需要执行额外的步骤。我一直在努力使这段代码工作,最后在 Apple 的网站上找到了这个:“重要的是,要在 iOS 12 及更高版本中使用此功能,请在 Xcode 中为您的应用程序启用访问 WiFi 信息功能。启用此功能后,Xcode 会自动将访问 WiFi 信息权利添加到您的权利文件和应用程序 ID。” https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo
回答by onnoweb
See CNCopyCurrentNetworkInfo in CaptiveNetwork: http://developer.apple.com/library/ios/#documentation/SystemConfiguration/Reference/CaptiveNetworkRef/Reference/reference.html.
请参阅 CaptiveNetwork 中的 CNCopyCurrentNetworkInfo:http: //developer.apple.com/library/ios/#documentation/SystemConfiguration/Reference/CaptiveNetworkRef/Reference/reference.html。
回答by n.Drake
Here's the short & sweet Swift version.
这是简短而甜蜜的 Swift 版本。
Remember to link and import the Framework:
请记住链接并导入框架:
import UIKit
import SystemConfiguration.CaptiveNetwork
Define the method:
定义方法:
func fetchSSIDInfo() -> CFDictionary? {
if let
ifs = CNCopySupportedInterfaces().takeUnretainedValue() as? [String],
ifName = ifs.first,
info = CNCopyCurrentNetworkInfo((ifName as CFStringRef))
{
return info.takeUnretainedValue()
}
return nil
}
Call the method when you need it:
在需要时调用该方法:
if let
ssidInfo = fetchSSIDInfo() as? [String:AnyObject],
ssID = ssidInfo["SSID"] as? String
{
println("SSID: \(ssID)")
} else {
println("SSID not found")
}
As mentioned elsewhere, this only works on your iDevice. When not on WiFi, the method will return nil – hence the optional.
正如其他地方提到的,这仅适用于您的 iDevice。当不在 WiFi 上时,该方法将返回 nil - 因此是可选的。
回答by Francois B
For iOS 13
对于 iOS 13
As from iOS 13 your app also needs Core Location access in order to use the CNCopyCurrentNetworkInfo
functionunless it configured the current network or has VPN configurations:
从 iOS 13 开始,您的应用程序还需要核心位置访问权限才能使用该CNCopyCurrentNetworkInfo
功能,除非它配置了当前网络或具有 VPN 配置:
So this is what you need (see apple documentation):
- Link the CoreLocation.framework
library
- Add location-services
as a UIRequiredDeviceCapabilities
Key/Value in Info.plist
- Add a NSLocationWhenInUseUsageDescription
Key/Value in Info.plistdescribing why your app requires Core Location
- Add the "Access WiFi Information" entitlement for your app
因此,这是你所需要的(见苹果文档):
-链接CoreLocation.framework
库
-添加location-services
为UIRequiredDeviceCapabilities
一个键/值Info.plist中
-添加NSLocationWhenInUseUsageDescription
一个键/值Info.plist中描述为什么您的应用程序需要核心定位
-添加“访问无线网络您的应用程序的信息”权利
Now as an Objective-C example, first check if location access has been accepted before reading the network info using CNCopyCurrentNetworkInfo
:
现在作为一个 Objective-C 示例,在使用CNCopyCurrentNetworkInfo
以下命令读取网络信息之前,首先检查位置访问是否已被接受:
- (void)fetchSSIDInfo {
NSString *ssid = NSLocalizedString(@"not_found", nil);
if (@available(iOS 13.0, *)) {
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
NSLog(@"User has explicitly denied authorization for this application, or location services are disabled in Settings.");
} else {
CLLocationManager* cllocation = [[CLLocationManager alloc] init];
if(![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
[cllocation requestWhenInUseAuthorization];
usleep(500);
return [self fetchSSIDInfo];
}
}
}
NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
id info = nil;
for (NSString *ifnam in ifs) {
info = (__bridge_transfer id)CNCopyCurrentNetworkInfo(
(__bridge CFStringRef)ifnam);
NSDictionary *infoDict = (NSDictionary *)info;
for (NSString *key in infoDict.allKeys) {
if ([key isEqualToString:@"SSID"]) {
ssid = [infoDict objectForKey:key];
}
}
}
...
...
}