如何在函数中返回 CLLocationManager didUpdateLocations 的值?
Posted
技术标签:
【中文标题】如何在函数中返回 CLLocationManager didUpdateLocations 的值?【英文标题】:How to return the value of CLLocationManager didUpdateLocations in function? 【发布时间】:2019-07-25 10:10:58 【问题描述】:我遇到的问题是,当我在其他类中调用 getCityName() 函数时,它返回 nil,因为 didUpdateLocations 需要更多时间来运行,如何解决这个异步问题?以及
import Foundation
import CoreLocation
class userCurrentLocation: NSObject, CLLocationManagerDelegate
var locationManager:CLLocationManager!
var cityName:String!
init(cityName:String)
super.init()
setUp()
func getCityName() -> String?
return cityName
func setUp()
if (CLLocationManager.locationServicesEnabled())
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
locations.last!.geocode placemark, error in
if let error = error as? CLError
print("CLError:", error)
return
else if let placemark = placemark?.first
self.cityName = placemark.locality ?? ""
manager.stopUpdatingLocation()
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
print(error)
extension CLLocation
func geocode(completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void)
CLGeocoder().reverseGeocodeLocation(self, completionHandler: completion)
【问题讨论】:
【参考方案1】:class userCurrentLocation: NSObject, CLLocationManagerDelegate
var locationManager:CLLocationManager!
var cityName:String!
//1. Add a closure callback
var didGetCity: ((String) -> Void)?
//2. Send City Name when received
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
locations.last!.geocode placemark, error in
if let error = error as? CLError
print("CLError:", error)
return
else if let placemark = placemark?.first
self.cityName = placemark.locality ?? ""
// Check for null
// Send city name in the completion block
if (self.didGetCity != nil)
self.didGetCity?(self.cityName)
manager.stopUpdatingLocation()
//3. Add code to your class where you need the city Name
var City : String?
let locationManager = userCurrentLocation (cityName: "")
locationManager.didGetCity =
[weak self] city in
self!.City = city
【讨论】:
如果你只是想强制解开它,那么使用[weak self]
没有多大意义。我建议您要么保留强大的self
,要么使用有条件的展开。
@Paulw11 你是对的。这是我的错误
另外,City
属性应该是 city
【参考方案2】:
您可以使用 Delegate 告诉主类一切准备就绪并使用该值
import Foundation
import CoreLocation
protocol userCurrentLocationDelegate: class
func userCurrentLocationDidGetLocation(_ userLocation: userCurrentLocation)
class userCurrentLocation: NSObject, CLLocationManagerDelegate
var locationManager:CLLocationManager!
var cityName:String!
weak var delegate: userCurrentLocationDelegate?
init(cityName:String)
super.init()
setUp()
func getCityName() -> String?
return cityName
func setUp()
if (CLLocationManager.locationServicesEnabled())
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
locations.last!.geocode placemark, error in
if let error = error as? CLError
print("CLError:", error)
return
else if let placemark = placemark?.first
self.cityName = placemark.locality ?? ""
manager.stopUpdatingLocation()
delegate?.userCurrentLocationDidGetLocation(self)
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
print(error)
extension CLLocation
func geocode(completion: @escaping (_ placemark: [CLPlacemark]?, _ error: Error?) -> Void)
CLGeocoder().reverseGeocodeLocation(self, completionHandler: completion)
在调用这个的主类中,使用这个回调中的委托来开始调用城市名称
【讨论】:
以上是关于如何在函数中返回 CLLocationManager didUpdateLocations 的值?的主要内容,如果未能解决你的问题,请参考以下文章