【问题标题】:CLLocation Manager in Swift to get Location of UserSwift 中的 CLLocation 管理器获取用户的位置
【发布时间】:2014-07-26 15:49:38
【问题描述】:

我正在尝试将 ObjC 中的旧应用程序转换为 Swift 作为练习,但遇到了一些问题。我在旧应用程序中使用它的方式是建立 CLLocation 管理器,然后我会使用:

manager = [[CLLocationManager alloc]init];
manager.delegate = self;
manager.desiredAccuracy = kCLLocationAccuracyBest;    
[manager startUpdatingLocation]

自动调用:

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
}

从那里我可以提取我需要的所有信息。但是很快,这种方法没有自动完成功能,我无法弄清楚如何重现它。文档说

startUpdatingLocation()

仍然会被委托调用,但它没有发生。

这是我目前所拥有的:

import UIKit
import corelocation

class ViewController: UIViewController,CLLocationManagerDelegate{

@IBOutlet var gpsResult : UILabel

var manager:CLLocationManager!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    manager = CLLocationManager()
    manager.delegate = self
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.startUpdatingLocation()
}

func locationManager(manager:CLLocationManager, didUpdateLocations locations:AnyObject[]) {
    println("locations = \(locations)")
    gpsResult.text = "success"
}
}

任何有关查看位置的帮助或指示将不胜感激。谢谢。

编辑:根据建议更新,但仍然无法正常工作

EDIT2:似乎是一些错误不允许该方法在 ViewController 中正常工作

【问题讨论】:

标签: cllocationmanager swift


【解决方案1】:

你错过了两件事。首先,您必须使用requestAlwaysAuthorizationrequestWhenInUseAuthorization() 请求许可。所以你的viewDidLoad() 应该是这样的:

var locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    locationManager.startUpdatingLocation()
}

其次,编辑你的Info.plistas indicated here

【讨论】:

  • 确保 info.plist 中有 iOS 8 的有效行,这是我的问题
【解决方案2】:

首先在plist文件中添加这两行

  1. NSLocationWhenInUseUsageDescription

  2. NSLocationAlwaysUsageDescription

那么这是类工作完成实现这个

import UIKit

import CoreLocation

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {

var window: UIWindow?
var locationManager: CLLocationManager!
var seenError : Bool = false
var locationFixAchieved : Bool = false
var locationStatus : NSString = "Not Started"

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    initLocationManager();
    return true
}

// Location Manager helper stuff
func initLocationManager() {
    seenError = false
    locationFixAchieved = false
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.locationServicesEnabled
    locationManager.desiredAccuracy = kCLLocationAccuracyBest

    locationManager.requestAlwaysAuthorization()
}

// Location Manager Delegate stuff
// If failed
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    locationManager.stopUpdatingLocation()
    if (error) {
        if (seenError == false) {
            seenError = true
           print(error)
        }
    }
}

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) {
    if (locationFixAchieved == false) {
        locationFixAchieved = true
        var locationArray = locations as NSArray
        var locationObj = locationArray.lastObject as CLLocation
        var coord = locationObj.coordinate

        println(coord.latitude)
        println(coord.longitude)
    }
}

// authorization status
func locationManager(manager: CLLocationManager!,
    didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        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
        }
        NSNotificationCenter.defaultCenter().postNotificationName("LabelHasbeenUpdated", object: nil)
        if (shouldIAllow == true) {
            NSLog("Location to Allowed")
            // Start location services
            locationManager.startUpdatingLocation()
        } else {
            NSLog("Denied access: \(locationStatus)")
        }
}
}

【讨论】:

  • 你能告诉我如何在我的 Controller.swift 中使用上述内容吗?
  • 您可以在任何地方使用,只需在您的 viewcontroler 中而不是 appdelegate 中编写此代码。这不会有任何不同。只需从 viewdidload() 调用 InitLocationManager() 其他一切都会一样...
  • 我试过了,但对我不起作用,我发布了一个关于它的问题here
  • 此代码有效,但只是第一次,一旦用户接受请求,locationManager.startUpdatingLocation() 就不会在后续应用程序运行中再次调用。
【解决方案3】:

我不知道为什么,但似乎startUpdatingLocation 没有在 iOS 7 模拟器上显示用户提示,但是当我手动启用它时,如果我使用较新形式的委托方法,它会按预期工作:

var manager:CLLocationManager!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    manager = CLLocationManager()
    manager.delegate = self
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.startUpdatingLocation()
}

func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) { // Updated to current array syntax [AnyObject] rather than AnyObject[]
    println("locations = \(locations)")
}

您使用的格式自 iOS 5 或 6 以来已被弃用,因此显然 swift 桥接层根本不支持它。

【讨论】:

  • 对不起,在这种情况下,“手动启用”是什么意思? @大卫
  • @SeanFitz 进入设置>隐私>位置并确保您的应用已启用。
  • @SeanFitz 如果您在设备上使用它,只要您不尝试使用已弃用的方法,它似乎就可以正常工作。
  • 我在我的设备上构建了代码,正如您在上面看到的,使用您向我展示的新方法,但 locationManager() 从未从 manager.startUpdatingLocation 调用。它只是完全没有任何作用。 @大卫
  • @SeanFitz 在现场设备上还是在模拟器上?进入设置>隐私>位置并确保您的应用程序已启用。
【解决方案4】:

有同样的问题。 didUpdateLocations - 没有工作。运行您的应用程序。转到设置页面 -> 隐私 -> 位置并关闭定位服务。 didFailWithError 将捕获有关缺少位置服务的错误。然后打开它。从那一刻起,didUpdateLocations 将捕获位置。

【讨论】:

    【解决方案5】:

    这是我非常简单的代码:

    首先在 General/Linked Frameworks and Libraries 中添加 Core Location 框架

    然后将以下内容添加到 Info.plist 中:

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>blablabla</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>blablabla</string>
    

    这是我的 ViewController.swift 文件:

    import UIKit
    import CoreLocation
    
    class ViewController: UIViewController, CLLocationManagerDelegate {
    
        var locationManager:CLLocationManager!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.requestAlwaysAuthorization()
            locationManager.startUpdatingLocation()
        }
    
    
        func locationManager(manager:CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            print("locations = \(locations)")
        }
    
    }
    

    【讨论】:

      【解决方案6】:

      对于 Swift 3

      import UIKit
      import CoreLocation
      
      class ViewController: UIViewController,CLLocationManagerDelegate {
      
      
          var locationManager:CLLocationManager!
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              locationManager = CLLocationManager()
              locationManager.delegate = self
              locationManager.desiredAccuracy = kCLLocationAccuracyBest
              locationManager.requestAlwaysAuthorization()
              locationManager.startUpdatingLocation()
      
              // Do any additional setup after loading the view, typically from a nib.
          }
      
          override func didReceiveMemoryWarning() {
              super.didReceiveMemoryWarning()
              // Dispose of any resources that can be recreated.
          }
      
          func locationManager(_ manager:CLLocationManager, didUpdateLocations locations: [CLLocation]) {
              print("locations = \(locations)")
          }
      
      
      }
      

      【讨论】:

        【解决方案7】:

        我希望有两种方法。

        var locationManager: CLLocationManager = CLLocationManager()
        var initialLocation :CLLocation?
        var updatedUserLocation :CLLocation?
        
        override func viewDidLoad() {
            super.viewDidLoad() {
        
            //MapView Location
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.requestWhenInUseAuthorization()
            locationManager.startUpdatingLocation()
            locationManager.startUpdatingHeading()
        }
        

        实现 CLLocationManagerDelegate :

        //CLLocationManager Delegate
        func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
            // This only works when user location is updated.
            gpsProviderStatusLabel.changeStatusToOn(gpsProviderStatusLabel)
        
        }
        
        func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        
            //Error indicates GPS permission restricted
        
            gpsProviderStatusLabel.changeStatusToOff(gpsProviderStatusLabel)
        
            //Initial Location
            initialLocation = locations.first
        
            //Getting Updated Location
            updatedUserLocation = locations.last
        }
        

        检查 CLLocationDelegate 授权:

        func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        
            //This method does real time status monitoring.
        
                switch status {
                case .NotDetermined:
                  print(".NotDetermined")
                  break
        
                case .AuthorizedAlways:
                  print(".AuthorizedAlways")
                  gpsProviderStatusLabel.changeStatusToOn(gpsProviderStatusLabel)
                  break
        
        
                case .Denied:
                  print(".Denied")
                  gpsProviderStatusLabel.changeStatusToOff(gpsProviderStatusLabel)
                  break
        
                case .AuthorizedWhenInUse:
                  print(".AuthorizedWhenInUse")
                  gpsProviderStatusLabel.changeStatusToOn(gpsProviderStatusLabel)
                  break
        
                case .Restricted:
                  print(".Restricted")
                  break
        
                default:
                  print("Unhandled authorization status")
                  break
        
                }
              }
        

        注意:changeStatusToOn 或 changeStatusToOff 是 UILabel 扩展方法,它使标签文本以绿色/红色颜色打开/关闭。

        【讨论】:

          【解决方案8】:

          别忘了添加 NSLocationWhenInUseUsageDescription 或 NSLocationAlwaysUsageDescription 在您的配置文件中(目标/信息/自定义 iOS 目标属性

          【讨论】:

            【解决方案9】:

            info.plist

            中添加 bellow 2 属性
            NSLocationWhenInUseUsageDescription : Location information is used for fraud prevention
            
            Privacy - Location Usage Description : Location information is used for fraud prevention
            

            【讨论】:

              【解决方案10】:

              如果您想默认更新用户位置,而不是每次都点击“模拟位置”,请转到

              YourProject-->Build Phases-->Link Binary with libraries-->Add corelocation.framework
              

              当您在模拟器中运行应用程序时,位置会自动/默认更新。在 Swift 2 中测试并运行!

              【讨论】:

              • 我只是关注并添加了 corelocation.framework,但它对我不起作用。
              • 不确定它是否是 XCode 特定版本的功能,但我正在使用它来跟踪用户的默认位置,用于天气应用
              【解决方案11】:

              这将请求许可并跟踪是否获得许可,否则退出并发出警报。按下后退按钮时停止跟踪。

              info.plist

              <key>NSLocationAlwaysUsageDescription</key>
              <string>Allow tracking while completing a survey</string>
              

              类:

              import UIKit
              import CoreLocation    
              
              class LocationViewController: BaseViewController, CLLocationManagerDelegate {
              
                      // MARK: Constants
              
                      private static let enableLocationServices = [
                          "title" : "Location",
                          "message" : "Enable location services",
                          "buttonTitle" : "OK"
                      ]
              
                      // MARK: Private variables
              
                      private var manager: CLLocationManager?
              
                      // MARK: UIViewCOntroller methods
              
                      @IBAction func backButtonPressed(sender : UIButton) {
                          stopTracking()
                          detatchLocationManager()
                          dismissViewControllerAnimated(true, completion: nil)
                      }
              
                      override func viewDidLoad() {
                          super.viewDidLoad()
              
                          attachLocationManager()    
                      }
              
                      // Mark: Location
              
                      func locationManager(manager: CLLocationManager,
                                           didChangeAuthorizationStatus status: CLAuthorizationStatus)
                      {
                          if status == .AuthorizedAlways {
                              manager.startUpdatingLocation()
                          } else if status != .NotDetermined {
                              showEnableLocationServicesAlert()
                          }
                      }
              
                      func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
                          for location in locations {
                              getDependencyService().getProject().appendLocationTrackingFile(location.timestamp, latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
                          }
                      }
              
                      // MARK: LocationViewController
              
                      private func attachLocationManager() {
                          manager = CLLocationManager()
                          manager?.delegate = self
                          manager?.desiredAccuracy = kCLLocationAccuracyBest
              
                          if CLLocationManager.authorizationStatus() != .AuthorizedAlways {
                              manager?.requestAlwaysAuthorization()
                          } else if CLLocationManager.locationServicesEnabled() {
                              startTracking()
                          }
                      }
              
                      private func detatchLocationManager() {
                          manager?.stopUpdatingLocation()
                          manager?.delegate = nil
                          manager = nil
                      }
              
                      private func startTracking() {
                          manager?.startUpdatingLocation()
                      }
              
                      private func stopTracking() {
                          manager?.stopUpdatingLocation()
                      }
              
                      private func showEnableLocationServicesAlert() {
              getDependencyService().getUiHelper().showAlert(FrogFirstSurveyViewController.enableLocationServices, completion: {
                              self.dismissViewControllerAnimated(true, completion: nil)
                          })
                      }
              
                  }
              

              【讨论】:

                【解决方案12】:

                斯威夫特:

                添加以下内容

                import CoreLocation
                class YourViewController: UIViewController
                {
                       var locationManager:CLLocationManager!
                }
                
                
                //MARK:- Location Manager
                extension YourViewController: CLLocationManagerDelegate {
                
                    func stratLocationManager()
                    {
                        locationManager = CLLocationManager()
                        locationManager.delegate = self
                        locationManager.desiredAccuracy = kCLLocationAccuracyBest
                        self.checkUsersLocationServicesAuthorization()
                        locationManager.startUpdatingLocation()
                
                    }
                
                    func checkUsersLocationServicesAuthorization(){
                        /// Check if user has authorized Total Plus to use Location Services
                        if CLLocationManager.locationServicesEnabled()
                        {
                            switch CLLocationManager.authorizationStatus()
                            {
                            case .notDetermined:
                                // Request when-in-use authorization initially
                                // This is the first and the ONLY time you will be able to ask the user for permission
                                self.locationManager.delegate = self
                                locationManager.requestWhenInUseAuthorization()
                                break
                
                            case .restricted, .denied:
                                // Disable location features
                                PrintLogs("Location Access Not Available")
                                break
                
                            case .authorizedWhenInUse, .authorizedAlways:
                                // Enable features that require location services here.
                                PrintLogs("Location Access Available")
                                break
                            }
                        }
                    }
                
                    func locationManager(_ manager:CLLocationManager, didUpdateLocations locations: [CLLocation]) {
                        print("locations = \(locations)")
                    }
                }
                

                【讨论】:

                  【解决方案13】:

                  只需调用 init(vc : UIViewController)。

                      import Foundation
                      import CoreLocation
                      import UIKit
                  
                  
                      class LocManager : NSObject{
                  
                  
                          var permission : ((Bool?)->())?
                  
                          private var locationManager : CLLocationManager!
                  
                          init(_ vc : UIViewController) {
                              super.init()
                              self.locationManager = CLLocationManager()
                              self.locationManager.delegate = vc as? CLLocationManagerDelegate
                              setUpLocationManagerDelegate()
                          }
                  
                  
                      }
                  
                      extension LocManager : CLLocationManagerDelegate {
                  
                          fileprivate func setUpLocationManagerDelegate(){
                                 locationManager = CLLocationManager()
                                 locationManager.delegate = self
                                 locationManager.desiredAccuracy = kCLLocationAccuracyBest
                                 locationManager.requestAlwaysAuthorization()
                             }
                  
                          func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
                  
                              if let lat  = locations.last?.coordinate.latitude, let long = locations.last?.coordinate.longitude{
                                  print("\n\nThe current Lat/Long Is Here\n\n")
                                  let coordinates = CLLocationCoordinate2D(latitude: lat, longitude: long)
                  
                              }else{
                                  print("Unable To Access Locaion")
                              }
                          }
                  
                          func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
                  
                              switch status {
                              case .authorizedAlways,.authorizedWhenInUse:
                                  print("Good to go and use location")
                                  locationManager.startUpdatingLocation()
                                  self.callPermisssionCompletion(val: true)
                  
                              case .denied:
                                  print("DENIED to go and use location")
                                  self.callPermisssionCompletion(val: false)
                  
                              case .restricted:
                                  print("DENIED to go and use location")
                                  self.callPermisssionCompletion(val: nil)
                  
                              case .notDetermined:
                                  print("DENIED to go and use location")
                                  self.callPermisssionCompletion(val: nil)
                  
                              default:
                                  print("Unable to read location :\(status)")
                              }
                          }
                  
                  
                          fileprivate func callPermisssionCompletion(val : Bool?){
                  
                              guard let comp = self.permission else {
                                  print("\n\n Unable to  locate completions \n\n")
                                  return
                              }
                              if let val =  val{
                                  comp(val)
                              }
                  
                          }
                  
                  
                      }
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2014-12-10
                    • 1970-01-01
                    • 2013-05-20
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多