ios - 使用 iOS App、Swift 获取设备/用户位置的问题

标签 ios swift core-location

设置:

  1. Xcode 7.3 (7D175)
  2. swift 2
  3. 设备是装有 iOS 9.3.1 的 iPad

我有一个名为 LocationUtility 的 Swift 类,我在 ViewController 中像这样使用它:

 let locationUtil = LocationUtility()
 locationUtil.initLocationManager()

initLocationManager() 函数将 CLLocationManager.delegate 设置为我的 LocationUtility 类:

func initLocationManager() {
    seenError = false
    locationFixAchieved = false
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest

    locationManager.requestAlwaysAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        locationManager.startUpdatingLocation()
    }
}

永远不会调用以下委托(delegate)函数:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])

我在 Info.plist 中设置了 NSLocationAlwaysUsageDescription 字符串

在我的 iPad 上,隐私 -> 定位服务已启用。

我的 LocationUtility 类是一个组合在一起的东西,主要是来自其他 stackoverflow 问题和有关 Swift 和 iOS 8 及更高版本中定位功能的答案的代码。从我的角度来看,我的应用程序和设备上的所有正确设置都可以接收位置信息。

这是我完整的 LocationUtility 类源代码:

import UIKit
import Foundation
import CoreLocation

class LocationUtility: UIViewController, CLLocationManagerDelegate {
    var locationStatus : NSString = "Not Started"
    var locationManager: CLLocationManager!
    var seenError : Bool = false
    var locationFixAchieved : Bool = false
    var currentLocation:CLLocation? = nil

    func initLocationManager() {
        seenError = false
        locationFixAchieved = false
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest

        locationManager.requestAlwaysAuthorization()

        if CLLocationManager.locationServicesEnabled() {
            //locationManager.delegate = self
            //locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()
        }

    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("LocationUtility -> didFailWithError()")
        locationManager.stopUpdatingLocation()
        if (seenError == false) {
            seenError = true
            print(error)
        }

    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("LocationUtility -> didUpdateLocations()")
        if (locationFixAchieved == false) {
            locationFixAchieved = true
            //var locationArray = locations as NSArray
            currentLocation = locations.last! as CLLocation
            let coord = currentLocation!.coordinate

            print("user current location")
            print(coord.latitude)
            print(coord.longitude)
        }
    }

    // authorization status
   func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
            print("LocationUtility -> didChangeAuthorizationStatus()!")

            var shouldIAllow = false

            switch status {
            case CLAuthorizationStatus.Restricted:
                locationStatus = "Restricted Access to location"
            case CLAuthorizationStatus.Denied:
                locationStatus = "User denied access to location"
            case CLAuthorizationStatus.NotDetermined:
                locationStatus = "Status not determined"
            default:
                locationStatus = "Allowed to location Access"
                shouldIAllow = true
            }

            if (shouldIAllow == true) {
                NSLog("Location to Allowed")
                // Start location services
                locationManager.startUpdatingLocation()
            } else {
                NSLog("Denied access: \(locationStatus)")
            }
    }

}

最佳答案

您描述的症状强烈表明您的 LocationUtility 实例正在被释放,这会释放 CLLocationManager 并停止整个过程。不清楚在哪里实例化 LocationUtility,但您需要确保它是在 CLLocationManager 执行其操作时实例将在内存中保持“事件”状态的某个位置。例如,如果 View Controller 被释放,那么它的实例变量将被释放,看起来它可能包括您的位置管理器。

您最初的问题是询问位置管理器是否必须位于应用程序委托(delegate)中。当然,它不是,但它确实必须在某个地方,以防止在进行位置更新时释放它。

如果您不确定 LocationManager 何时被释放,请尝试对其执行 deinit 并在该方法上设置断点。

关于ios - 使用 iOS App、Swift 获取设备/用户位置的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36668479/

相关文章:

ios - 如何为 UITableViewCell 实现摇动动画

iOS Swift 将日历组件 int 月份转换为中型字符串月份

iphone - 如何解决 Xcode 4.1 (LION) GPS 错误?

iOS/iPhone 可达性 - 如何仅在互联网丢失/无法使用 Reachability.m/.h 时检查

ios - 将 View 推到标签栏 Controller 中的导航 Controller 上不会产生动画

ios - 如何使用 iPhone X 的 faceID 数据

ios - 如何让动画在 SwiftUI 的 ScrollView 中工作? SwiftUI 中的 Accordion 风格动画

ios - 弱属性无法在 swift 3.0 中初始化

ios - 当应用程序处于后台时,我可以将用户的当前位置发送到服务器吗?

iphone - 获取 iPhone 当前位置的最简单方法是什么?