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名稱的時候向用戶申請臨時開啟一次精確位置權(quán)限了。
???????? Demo地址:LocationDemo
2.1 申請權(quán)限需要調(diào)用 - (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey
方法瓢省。
??:該方法起作用的前提是用戶已經(jīng)允許了定位,即授權(quán)狀態(tài)不是 kCLAuthorizationStatusNotDetermined
或 kCLAuthorizationStatusRestricted
或 kCLAuthorizationStatusDenied
痊班。
2.2 在申請臨時開啟一次精確位置權(quán)限前净捅,需要在Info.plist中進(jìn)行配置。
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
對應(yīng)的國際化內(nèi)容具钥,例如:
WantsToGetWiFiSSID = "Your precise location will be used to get the current Wi-Fi SSID.";
- 如果未提供國際化內(nèi)容豆村,則使用
Info.plist
中的說明描述;
2.3 代碼實現(xiàn)
1?? 申請臨時開啟一次精確位置權(quán)限:
if (@available(iOS 14.0, *)) {
BOOL isFullAccuracy = self.locationManager.accuracyAuthorization == CLAccuracyAuthorizationFullAccuracy;
if (!isFullAccuracy) {
// 向用戶申請臨時開啟一次精確位置權(quán)限
[self.locationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:@"WantsToGetWiFiSSID"];
}
}
2?? 在授權(quán)狀態(tài)改變的代理方法中再次獲取WiFi名稱骂删,更新WiFi名稱的顯示:
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager API_AVAILABLE(ios(14.0)) {
// 1. 定位權(quán)限狀態(tài)
CLAuthorizationStatus status = manager.authorizationStatus;
// 2. 精確定位權(quán)限狀態(tài)
CLAccuracyAuthorization accuracyStatus = manager.accuracyAuthorization;
if (accuracyStatus == CLAccuracyAuthorizationFullAccuracy) {
NSLog(@"精確定位已開啟");
} else {
NSLog(@"精確定位未開啟");
}
NSString *wifiName = [ViewController wifiName];
self.nameLabel.text = [NSString stringWithFormat:@"WiFi名稱: %@", wifiName];
}
2.4 臨時獲取的精確位置權(quán)限說明
2.4.1 權(quán)限會自動過期掌动,當(dāng)用戶在使用App時(如App在前臺)不會過期。
我的測試情況:
- 前臺 --> 后臺(大概10s內(nèi)) --> 前臺宁玫,不會過期粗恢;
- 前臺 --> 后臺(超過大概10s) --> 前臺,過期欧瘪;
2.4.2 App開啟了持續(xù)的后臺定位眷射,不會過期。
- ??? 添加后臺定位的配置
在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
妖碉,否則會產(chǎn)生致命錯誤涌庭。如果已在
Capability
中配置好了,但未允許后臺定位欧宜,則不會在后臺進(jìn)行定位坐榆,也不會產(chǎn)生錯誤。
3. iOS14 CLLocationManager 類中棄用的方法
- 類方法
[CLLocationManager authorizationStatus]
已棄用冗茸,需調(diào)用實例屬性:self.locationManager.authorizationStatus
- 授權(quán)狀態(tài)改變的代理方法的棄用:
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. 定位權(quán)限說明
高德開放平臺的文檔【定位權(quán)限說明】中詳細(xì)描述了 iOS 8.0 - iOS 14.0 前臺定位與后臺定位的配置情況席镀。