You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中CLLocationManagerDelegate未触发问题求助

问题:CLLocationManager代理方法完全不触发,调用startUpdatingLocation无响应

实现的LocationManager单例类用于获取用户坐标,昨晚还正常工作,今天突然失效。调用locationManager.startUpdatingLocation()后,CLLocationManager的所有代理方法都没触发——既没有返回坐标结果,也没有错误回调。已经确认单例不会被销毁,且locationManager.delegate指向LocationManager实例(非nil)。翻遍了CLLocationManager相关的帖子,还是没解决。

Info.plist配置

<key>NSWidgetUsesLocation</key>
<true/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Enable Weather for Power Users</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Enable Weather for Power Users</string>

LocationManager.swift代码

import Foundation
import CoreLocation

// Usage
// LocationManager.Instance.getCoordinateString(() { coordinatesString
//  print("Current coordinates string: \(coordinatesString!)")
//)

class LocationManager: NSObject, CLLocationManagerDelegate {
    static let Instance = LocationManager()
    
    private var locationManager = CLLocationManager()
    private var authorizeCompletion: (() -> Void)?
    private var updateCompletion: ((_ coordinateString: String?) -> Void)?
    
    private override init() {
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
    }
    
    public func requestPermission(completion: @escaping () -> Void) {
        if status != .notDetermined {
            completion()
            return
        }
        
        authorizeCompletion = completion
        locationManager.requestAlwaysAuthorization()
    }
    
    public var status: CLAuthorizationStatus {
        get {
            return locationManager.authorizationStatus
        }
    }
    
    func getCoordinateString(completion: @escaping (_ coordinateString: String?) -> Void) {
        print("LocationManager.getCoordinateString() \(status)", locationManager.delegate)
        
        if status == .denied || status == .restricted {
                //          print("LocationManager.locationManager(): ERROR Permission:", status)
            completion(nil)
            return
        }
        
        if status == .notDetermined {
            completion(nil) // Temporary return basic weather
            
            requestPermission(completion: { [self] in
                updateCompletion = completion
                locationManager.startUpdatingLocation()
                    //              locationManager.requestLocation()
            })
            return
        }
        
        updateCompletion = completion
        locationManager.startUpdatingLocation()
    }
    
    // MARK: CLLocationManagerDelegate
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        print("LocationManager.locationManager(): Authorization completed", status)
        authorizeCompletion?()
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("LocationManager.locationManager(): didUpdateLocations")
        
        guard let location = locations.last else {
            print("LocationManager.locationManager(): ERROR No coodinate found")
            updateCompletion?(nil)
            updateCompletion = nil
            return
        }
        
        // Stop updating location after the first result
        locationManager.stopUpdatingLocation()
        
        let latitude = String(format: "%.4f", location.coordinate.latitude)
        let longitude = String(format: "%.4f", location.coordinate.longitude)
        let result = "\(latitude),\(longitude)"
        
        // Call completion handler if it's set
        updateCompletion?(result)
        updateCompletion = nil
        
        print("LocationManager.locationManager(): Coordinate \(result)")
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("LocationManager.locationManager(): ERROR \(error.localizedDescription)")
        updateCompletion?(nil)
        updateCompletion = nil
        locationManager.stopUpdatingLocation()
    }
}

已做测试

  • iOS模拟器测试
  • 通过Testflight和Xcode调试在真机上测试
  • 回滚代码到之前正常版本

奇怪现象

  • 创建干净项目,放入相同的LocationManager.swift代码,在iOS模拟器上完美运行
  • 干净项目中即使不添加Info.plist的定位权限键,至少会返回错误,但实际项目中完全无任何反应

干净项目中可正常运行的调用代码

class GameScene: SKScene {
    override func didMove(to view: SKView) {
        LocationManager.Instance.requestPermission {
            LocationManager.Instance.getCoordinateString(completion: {coordinateString in
                print("GameScene", coordinateString)
            })
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:56:07