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
相关产品推荐
相关产品推荐

