加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 错误:’Delegate必须响应locationManager:didUpdateL

发布时间:2020-12-14 04:48:13 所属栏目:百科 来源:网络整理
导读:所以我想在用户点击按钮时收集用户位置,并稍后在我的应用中使用该位置.使用我当前的实现,当点击按钮时,应该提示用户允许共享位置,然后他们应该登录到应用程序(如果您想知道的话,通过Firebase匿名),并且应该打印用户位置信息到控制台.提示有效,但是在按下允许
所以我想在用户点击按钮时收集用户位置,并稍后在我的应用中使用该位置.使用我当前的实现,当点击按钮时,应该提示用户允许共享位置,然后他们应该登录到应用程序(如果您想知道的话,通过Firebase匿名),并且应该打印用户位置信息到控制台.提示有效,但是在按下允许位置按钮后,我的应用程序因未捕获的异常’NSInternalInconsistencyException’而终止

原因是’委托必须响应locationManager:didUpdateLocations:’

这很奇怪,因为我的代码中有一个didUpdateLocations:函数.

我不知道发生了什么,任何帮助表示赞赏.我的ViewController代码如下,谢谢!

/*
* Copyright (c) 2016 Ahad Sheriff
*
*/

import UIKit
import Firebase
import CoreLocation

class LoginViewController: UIViewController {

    // MARK: Properties
    var ref: FIRDatabaseReference! // 1
    var userID: String = ""

    var locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        ref = FIRDatabase.database().reference() // 2
    }

    @IBAction func loginDidTouch(sender: AnyObject) {

        //ask user to enable location services
        locationManager.requestWhenInUseAuthorization()

        if CLLocationManager.locationServicesEnabled() {
            //collect user's location
            locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
            locationManager.requestLocation()
            locationManager.startUpdatingLocation()

            let location = self.locationManager.location

            var latitude: Double = location!.coordinate.latitude
            var longitude: Double = location!.coordinate.longitude

            print("current latitude :: (latitude)")
            print("current longitude :: (longitude)")

            //Log in to application anonymously using Firebase
            FIRAuth.auth()?.signInAnonymouslyWithCompletion() { (user,error) in
                if let user = user {
                    print("User is signed in with uid: ",user.uid)
                    self.userID = user.uid
                } else {
                    print("No user is signed in.")
                }

                self.performSegueWithIdentifier("LoginToChat",sender: nil)

            }

        }

        else {
            print("Unable to determine location")
        }

    }

    override func prepareForSegue(segue: UIStoryboardSegue,sender: AnyObject?) {
        super.prepareForSegue(segue,sender: sender)
        let navVc = segue.destinationViewController as! UINavigationController // 1
        let chatVc = navVc.viewControllers.first as! ChatViewController // 2
        chatVc.senderId = userID // 3
        chatVc.senderDisplayName = "" // 4
    }

    func locationManager(manager: CLLocationManager!,didUpdateLocations locations: [AnyObject]!)
    {
        //--- CLGeocode to get address of current location ---//
        CLGeocoder().reverseGeocodeLocation(manager.location!,completionHandler: {(placemarks,error)->Void in

            if (error != nil)
            {
                print("Reverse geocoder failed with error" + error!.localizedDescription)
                return
            }

            if placemarks!.count > 0
            {
                let pm = placemarks![0] as CLPlacemark
                self.displayLocationInfo(pm)
            }
            else
            {
                print("Problem with the data received from geocoder")
            }
        })

    }


    func displayLocationInfo(placemark: CLPlacemark?)
    {
        if let containsPlacemark = placemark
        {
            //stop updating location
            locationManager.stopUpdatingLocation()

            let locality = (containsPlacemark.locality != nil) ? containsPlacemark.locality : ""
            let postalCode = (containsPlacemark.postalCode != nil) ? containsPlacemark.postalCode : ""
            let administrativeArea = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea : ""
            let country = (containsPlacemark.country != nil) ? containsPlacemark.country : ""

            print(locality)
            print(postalCode)
            print(administrativeArea)
            print(country)
        }

    }


    func locationManager(manager: CLLocationManager!,didFailWithError error: NSError!) {
        print("Error while updating location " + error.localizedDescription)
    }


}

解决方法

首先,明确添加您确认CLLocationManagerDelegate:

class LoginViewController: UIViewController,CLLocationManagerDelegate

其次,为CLLocationManager设置委托属性:

override func viewDidLoad() {
    super.viewDidLoad()
    locationManager.delegate = self
    ref = FIRDatabase.database().reference()
}

第三,在CLLocationManagerDelegate doc中,我看到了与didUpdateLocations和didFailWithError方法的声明不同:

func locationManager(_ manager: CLLocationManager,didUpdateLocations locations: [CLLocation])
func locationManager(_ manager: CLLocationManager,didFailWithError error: NSError)

此外,您在代码中几乎没有其他问题.它们都是关于不安全的展开.你不应该使用不安全的展开!到处.这样做是为了杀死选择哲学.另一方面,做正确的事情可以大大提高应用的稳定性.在loginDidTouch函数中进行以下更正:

var latitude: Double? = location?.coordinate.latitude
var longitude: Double? = location?.coordinate.longitude

当您第一次调用此函数时,您的位置尚未确定(将以异步方式确定,您将获得委托方法中的位置),这就是使用force unwrapp时出现致命错误的原因.在didUpdateLocations函数中:

if let pm = placemarks?.first
{
    self.displayLocationInfo(pm)  
}

这部分代码的更正比原始代码短,并且可以防止您同时发生两次可能的崩溃 – 当地标为nil且地标不是nil时,则为空数组

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读