You need to enable JavaScript to run this app. iOS12.3+ Objective-C 定位:废弃didUpdateToLocation方法替换及坐标不更新解决
优惠活动
大模型
产品
解决方案
定价
更多

iOS12.3+ Objective-C 定位:废弃didUpdateToLocation方法替换及坐标不更新解决

核心问题根因
  • 你遇到的编译警告,源于使用了从iOS 6.0就被苹果标记为废弃的didUpdateToLocation:fromLocation: 代理方法。你适配的iOS12.3系统已经完全不会回调这个方法,哪怕你把代码逻辑写得完全正确,这个方法也永远不会被系统触发,所以点按钮之后没有任何回调、标签不更新是必然结果。
  • 现有代码还存在两个会导致定位完全失效的硬伤:
    • 没有在Info.plist中声明定位权限的用途描述。按照iOS的权限规则,缺少对应描述时,系统会静默拦截所有定位请求,既不会弹出授权框,也不会触发定位失败的回调流程,从外部看就是点按钮完全没反应。
    • 没有主动触发定位权限的申请流程,也没有做权限状态判断,在未获得授权的状态下直接调用startUpdatingLocation,系统会直接静默拒绝请求。
兼容iOS12.3的替代方案

苹果从iOS 5.0开始就推出了完全向下兼容的新代理方法locationManager:didUpdateLocations:,这个方法会把连续的定位结果通过数组传回来,适配从iOS12.3到最新系统的所有版本,没有任何废弃风险。
使用这个方法替换原废弃方法的同时,补上权限申请、无效位置过滤的逻辑,就能保证正常拿到定位数据。

可直接落地的代码调整

第一步:配置Info.plist必填项

在项目的Info.plist文件中新增以下键值对,否则权限申请流程无法触发:

  • 新增Privacy - Location When In Use Usage Description 键,对应的值填写定位用途说明,比如“需要获取当前位置以展示经纬度坐标信息”

第二步:调整按钮点击的权限判断逻辑

替换原getCurrentLocation: 方法的代码,补充权限状态判断和申请流程:

- (IBAction)getCurrentLocation:(UIButton *)sender
{
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    
    // 获取当前App的定位权限状态
    CLAuthorizationStatus authStatus = [CLLocationManager authorizationStatus];
    if (authStatus == kCLAuthorizationStatusNotDetermined) {
        // 用户尚未做过授权选择,主动弹出授权申请框
        [locationManager requestWhenInUseAuthorization];
    } else if (authStatus == kCLAuthorizationStatusAuthorizedWhenInUse || authStatus == kCLAuthorizationStatusAuthorizedAlways) {
        // 已经获得授权,直接启动定位
        [locationManager startUpdatingLocation];
    } else {
        // 权限被永久拒绝,打印日志引导用户去系统设置开启权限
        NSLog(@"定位权限已被拒绝,请前往系统设置中为App开启定位权限");
    }
}

第三步:替换废弃的定位回调方法

直接删除原来的didUpdateToLocation:fromLocation: 方法,替换为新的兼容代理方法,同时补充无效位置过滤逻辑,避免拿到缓存的旧定位数据:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    // 取数组中最新的定位结果
    CLLocation *currentLocation = locations.lastObject;
    
    // 过滤超过5秒的缓存旧位置
    NSTimeInterval locationAge = -[currentLocation.timestamp timeIntervalSinceNow];
    if (locationAge > 5.0) {
        return;
    }
    // 过滤精度为负的无效定位
    if (currentLocation.horizontalAccuracy < 0) {
        return;
    }
    
    NSLog(@"获取到有效定位:%@", currentLocation);
    // 更新经纬度标签
    if (currentLocation != nil) {
        longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
        lattitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    }
    
    // 拿到有效定位后立即停止更新,减少设备耗电
    [locationManager stopUpdatingLocation];
    
    NSLog(@"开始反向解析地理位置信息");
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"地址解析结果:%@,错误信息:%@", placemarks, error);
        if (error == nil && placemarks.count > 0) {
            self->placemark = placemarks.lastObject;
            self->addressLabel.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@",
                           self->placemark.subThoroughfare, self->placemark.thoroughfare,
                           self->placemark.postalCode, self->placemark.locality,
                           self->placemark.administrativeArea,
                           self->placemark.country];
        } else {
            NSLog(@"地址解析失败:%@", error.debugDescription);
        }
    }];
}
真机测试注意事项
  • 首次点击按钮时,注意观察系统是否弹出定位授权框,如果没有弹出,优先检查Info.plist里的权限描述键名是否拼写正确、值是否为空
  • 如果已经授权但长时间拿不到定位,尽量在靠近窗边的位置测试,iPhone5s没有辅助的高精度定位芯片,室内GPS信号弱时首次定位会需要更长时间
  • 优先在真机上测试逻辑,不要用模拟器的定位功能代替真机验证,避免出现兼容性误判
参考资源方向
  • 苹果官方CoreLocation框架开发指南,内容覆盖了从iOS12开始的全版本适配规则、权限处理逻辑
  • 开源项目参考可以直接在GitHub站内搜索带“CoreLocation + Objective-C + iOS12适配”标签的项目,优先选择代码中没有使用废弃API、最近有维护更新的Demo学习。

内容的提问来源于stack exchange,提问作者THEJAS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 06:57:06