Swift   发布时间:2022-03-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了swift – 错误:’Delegate必须响应locationManager:didUpdateLocations:’收集用户位置时大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

所以我想在用户点击按钮时收集用户位置,并稍后在我的应用中使用该位置.使用我当前的实现,当点击按钮时,应该提示用户允许共享位置,然后他们应该登录到应用程序(如果您想知道的话,通过Firebase匿名),并且应该打印用户位置信息到控制台.提示有效,但是在按下允许位置按钮后,我的应用程序因未捕获的异常’NSInternalInconsistencyException’而终止 原因是’委托必须响应loca
所以我想在用户点击按钮时收集用户位置,并稍后在我的应用中使用该位置.使用我当前的实现,当点击按钮时,应该提示用户允许共享位置,然后他们应该登录到应用程序(如果您想知道的话,通过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时,则为空数组

大佬总结

以上是大佬教程为你收集整理的swift – 错误:’Delegate必须响应locationManager:didUpdateLocations:’收集用户位置时全部内容,希望文章能够帮你解决swift – 错误:’Delegate必须响应locationManager:didUpdateLocations:’收集用户位置时所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。