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

Posted

技术标签:

【中文标题】使用 iOS App、Swift 获取设备/用户位置的问题【英文标题】:Issues getting device/user location with iOS App, Swift 【发布时间】:2016-04-16 19:07:06 【问题描述】:

设置:

    Xcode 7.3 (7D175) 斯威夫特 2 设备是装有 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()
    

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

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

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

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

我的 LocationUtility 类是与其他有关 Swift 和 iOS 8 及更高版本中位置功能的 *** 问题和答案的代码放在一起的。从我的角度来看,我的 APP 和设备上的所有设置都正确,可以接收位置信息。

这是我完整的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)")
            
    


【问题讨论】:

感谢@Roee84 我更改了我的问题“标题”并编辑了我的问题,以便我可以在代表问题之外提供进一步的帮助,感谢您的反馈。 didChangeAuthorizationStatus 方法是否被调用过?如果是这样,status 的值是多少? didChangeAuthorizationStatus 也没有被调用,这让我觉得我设置的委托有问题,但我的 LocationUtility 类确实实现了 CLLocationManagerDelegate... 【参考方案1】:

您描述的症状强烈表明您的 LocationUtility 实例正在被释放,这将释放 CLLocationManager 并停止整个过程。目前尚不清楚您在哪里实例化LocationUtility,但您需要确保它是某个实例将在内存中保持“活动”的位置,而CLLocationManager 执行它的操作。例如,如果视图控制器被释放,那么它的实例变量将被释放,看起来它可能包括你的位置管理器。

您的问题最初询问位置经理是否必须在应用委托中。当然不是,但它确实必须在某个地方可以防止它在位置更新进行时被释放。

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

【讨论】:

是的,我在想一些类似的事情,但假设我的 ViewController 在我留在应用程序的映射屏幕上时没有被释放,但我会在这里测试 deinit 并回复你,感谢您的建议

以上是关于使用 iOS App、Swift 获取设备/用户位置的问题的主要内容,如果未能解决你的问题,请参考以下文章

怎么获取ios 设备上 所有app的信息

2020-09-07 手机设备唯一标识

iOS获取设备唯一编号,就算删除app从新安装也不变的方法

写入不属于当前设备的 Parse Installation 类对象 PFInstallation iOS Swift 3 FROM CLIENT APP

Swift:如何以编程方式获取iOS设备的唯一标识符?

如何检测 iOS App 是由特定用户(不是在特定设备上)首次启动的?