旧Xcode项目(iPhone4/3GS时期)如何启用定位服务?
旧Xcode项目在Xcode 14里启用定位服务的解决办法
1. 给Info.plist添加权限描述
iOS 8之后的系统强制要求,必须在Info.plist里明确说明使用定位的用途,否则不会弹出授权请求。旧项目(iPhone4/3GS时期的iOS版本无此要求)肯定缺这项配置,按你的需求选对应的键添加:
- 若后台也需要定位权限:添加
NSLocationAlwaysAndWhenInUseUsageDescription,值写比如“需要获取你的位置来提供导航/打卡服务” - 若仅在APP前台使用定位:添加
NSLocationWhenInUseUsageDescription,值写对应的用途即可 - 注意:旧的
NSLocationUsageDescription在iOS 10及以后已失效,必须用上面两个新键
添加方式二选一:
- 右键点击Info.plist,选择
Open As -> Source Code,插入以下代码(按需选其一):
<!-- 后台+前台定位权限描述 --> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>需要获取你的位置来提供相关服务</string> <!-- 仅前台定位权限描述 --> <key>NSLocationWhenInUseUsageDescription</key> <string>需要获取你的位置来提供相关服务</string>
- 或者在Xcode中进入项目target的
Info面板,找到Custom iOS Target Properties,点击“+”直接输入键名,再填写描述文本。
2. 更新定位请求代码
旧项目的代码可能直接启动定位,现在必须先申请权限才能获取位置,示例代码如下:
Swift版
import CoreLocation class LocationHandler: NSObject, CLLocationManagerDelegate { let locManager = CLLocationManager() override init() { super.init() locManager.delegate = self // 先检查当前权限状态 let status = locManager.authorizationStatus if status == .notDetermined { // 按需替换为requestAlwaysAuthorization(后台权限) locManager.requestWhenInUseAuthorization() } else if status == .authorizedWhenInUse || status == .authorizedAlways { locManager.startUpdatingLocation() } } // 权限状态变化时触发 func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { let status = manager.authorizationStatus if status == .authorizedWhenInUse || status == .authorizedAlways { manager.startUpdatingLocation() } } // 获取到位置信息的回调 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let latestLoc = locations.last { // 在这里处理拿到的位置数据 } } }
Objective-C版
#import <CoreLocation/CoreLocation.h> @interface LocationHandler : NSObject <CLLocationManagerDelegate> @property (nonatomic, strong) CLLocationManager *locManager; @end @implementation LocationHandler - (instancetype)init { self = [super init]; if (self) { self.locManager = [[CLLocationManager alloc] init]; self.locManager.delegate = self; CLAuthorizationStatus status = [self.locManager authorizationStatus]; if (status == kCLAuthorizationStatusNotDetermined) { // 按需替换为requestAlwaysAuthorization [self.locManager requestWhenInUseAuthorization]; } else if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusAuthorizedAlways) { [self.locManager startUpdatingLocation]; } } return self; } - (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager { CLAuthorizationStatus status = [manager authorizationStatus]; if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusAuthorizedAlways) { [manager startUpdatingLocation]; } } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { CLLocation *latestLoc = locations.lastObject; // 处理位置信息 } @end
3. 检查基础设置
- 确认测试设备的定位服务已开启:设置 -> 隐私与安全性 -> 定位服务
- 若之前误拒过权限,去设置 -> 你的APP -> 位置里重新开启权限
- 检查项目Info.plist中是否存在禁用定位的配置,避免无效操作
4. 可选:适配iOS14+精确位置权限
iOS14之后默认提供模糊位置,若需要精确坐标:
- 在Info.plist中添加
NSLocationDefaultAccuracyReducedDescription,说明需要精确位置的原因 - 调用
locManager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: "YourPurposeKey")申请临时精确权限,或配合Info.plist描述直接获取永久精确权限
内容的提问来源于stack exchange,提问作者doctor
相关产品推荐
相关产品推荐

