1. 问题
在 iOS14 中如果不允许精确定位,那么就获取不到WiFi的名称了。
我的项目中获取WiFi名称的方式:
+ (NSString *)wifiName {
NSArray *interfaces = CFBridgingRelease(CNCopySupportedInterfaces());
id info = nil;
for (NSString *interfaceName in interfaces) {
info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((CFStringRef)interfaceName);
if (info) {
break;
}
}
NSDictionary *infoDic = (NSDictionary *)info;
NSString *ssid = [infoDic objectForKey:@"SSID"]; // WiFi的名称
NSString *bssid = [infoDic objectForKey:@"BSSID"]; // WiFi的mac地址
NSLog(@"WiFi SSID = %@, MAC = %@", ssid, bssid);
return ssid;
}
2. 解决
不允许精确定位就获取不到WiFi名称,那么只有在获取WiFi名称的时候向用户申请临时开启一次精确位置权限了。
👉👉👉👉 Demo地址:LocationDemo
2.1 申请权限需要调用 - (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey
方法。
⚠️:该方法起作用的前提是用户已经允许了定位,即授权状态不是 kCLAuthorizationStatusNotDetermined
或 kCLAuthorizationStatusRestricted
或 kCLAuthorizationStatusDenied
。
2.2 在申请临时开启一次精确位置权限前,需要在Info.plist中进行配置。
2.2.1 Info.plist 中的配置
- 添加项目:
NSLocationTemporaryUsageDescriptionDictionary
,即:Privacy - Location Temporary Usage Description Dictionary
; - 在以上项目中添加键值对:
PurposeKey : 说明描述
,针对不同的使用场景,可以添加多个键值对。例如:
WantsToGetWiFiSSID : Your precise location will be used to get the current Wi-Fi SSID.
WantsToNavigate : Your precise location will be used to calculate a route and allow you to use turn-by-turn directions.
2.2.2 说明描述的国际化
- 需要在
InfoPlist.strings
中添加PurposeKey
对应的国际化内容,例如:
WantsToGetWiFiSSID = "Your precise location will be used to get the current Wi-Fi SSID.";
- 如果未提供国际化内容,则使用
Info.plist
中的说明描述;
2.3 代码实现
1️⃣ 申请临时开启一次精确位置权限:
if (@available(iOS 14.0, *)) {
BOOL isFullAccuracy = self.locationManager.accuracyAuthorization == CLAccuracyAuthorizationFullAccuracy;
if (!isFullAccuracy) {
// 向用户申请临时开启一次精确位置权限
[self.locationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:@"WantsToGetWiFiSSID"];
}
}
2️⃣ 在授权状态改变的代理方法中再次获取WiFi名称,更新WiFi名称的显示:
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager API_AVAILABLE(ios(14.0)) {
// 1. 定位权限状态
CLAuthorizationStatus status = manager.authorizationStatus;
// 2. 精确定位权限状态
CLAccuracyAuthorization accuracyStatus = manager.accuracyAuthorization;
if (accuracyStatus == CLAccuracyAuthorizationFullAccuracy) {
NSLog(@"精确定位已开启");
} else {
NSLog(@"精确定位未开启");
}
NSString *wifiName = [ViewController wifiName];
self.nameLabel.text = [NSString stringWithFormat:@"WiFi名称: %@", wifiName];
}
2.4 临时获取的精确位置权限说明
2.4.1 权限会自动过期,当用户在使用App时(如App在前台)不会过期。
我的测试情况:
- 前台 --> 后台(大概10s内) --> 前台,不会过期;
- 前台 --> 后台(超过大概10s) --> 前台,过期;
2.4.2 App开启了持续的后台定位,不会过期。
- 🅰️ 添加后台定位的配置
在Xcode的Capability
中配置Background Modes
的Location updates
。
With
UIBackgroundModes
set to include "location" inInfo.plist
, you must also set this property to YES at runtime whenever calling -startUpdatingLocation with the intent to continue in the background.
- 🅱️ 允许后台定位:
self.locationManager.allowsBackgroundLocationUpdates = YES;
重要提示:Setting this property to YES when UIBackgroundModes does not include "location" is a fatal error.
即:允许后台定位的前提是在Capability
中配置了Background Modes
的Location updates
,否则会产生致命错误。如果已在
Capability
中配置好了,但未允许后台定位,则不会在后台进行定位,也不会产生错误。
3. iOS14 CLLocationManager 类中弃用的方法
- 类方法
[CLLocationManager authorizationStatus]
已弃用,需调用实例属性:self.locationManager.authorizationStatus
- 授权状态改变的代理方法的弃用:
locationManager:didChangeAuthorizationStatus:
-->locationManagerDidChangeAuthorization:
/*
* locationManager:didChangeAuthorizationStatus:
*
* Discussion:
* Invoked when the authorization status changes for this application.
*/
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status API_DEPRECATED_WITH_REPLACEMENT("-locationManagerDidChangeAuthorization:", ios(4.2, 14.0), macos(10.7, 11.0), watchos(1.0, 7.0), tvos(9.0, 14.0));
/*
* locationManagerDidChangeAuthorization:
*
* Discussion:
* Invoked when either the authorizationStatus or
* accuracyAuthorization properties change
*/
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager API_AVAILABLE(ios(14.0), macos(11.0), watchos(7.0), tvos(14.0));
4. 定位权限说明
高德开放平台的文档【定位权限说明】中详细描述了 iOS 8.0 - iOS 14.0 前台定位与后台定位的配置情况。