我试图查看用户是否在某个地址的某个距离内。我已成功设法获取用户位置,并使用转发地理编码转换地址。我留下了两组坐标。我试图做一个if声明说他们是否在“距离”内,打印一些东西!
目前,当我打印地标功能内的坐标时,我得到了所需的坐标。当我打电话给他们创建eventLatitude和eventLongitude时,他们变成0.0。我知道这是一个异常的问题,但我不确定解决这个问题的对象。有人可以举个例子。
我的代码如下
在viewdidload之前我有这些变量
var placemarkLongitude = CLLocationDegrees()
var placemarkLatitude = CLLocationDegrees()
然后在函数内部我将这些变量设置为地标坐标
if let objects = objects {
for object in objects {
self.geocoder = CLGeocoder()
//get address from object
let COAddress = object.objectForKey("Address")as! String
let COCity = object.objectForKey("City")as! String
let COState = object.objectForKey("State")as! String
let COZipCode = object.objectForKey("ZipCode")as! String
let combinedAddress = "\(COAddress) \(COCity) \(COState) \(COZipCode)" //all parts of address
print(combinedAddress)
//make address a location
self.geocoder.geocodeAddressString(combinedAddress, completionHandler: {(placemarks, error) -> Void in
if(error != nil)
{
print("Error", error)
}
else if let placemark = placemarks?[0]
{
let placemark = placemarks![0]
self.placemarkLatitude = (placemark.location?.coordinate.latitude)! //THIS RETURNS A VALUE
self.placemarkLongitude = (placemark.location?.coordinate.longitude)! //THIS RETURNS A VALUE
print("Longitude: ", self.placemarkLongitude, " Latitude: ", self.placemarkLatitude)
}
})
// user location
let userLatitude = self.locationManager.location?.coordinate.latitude //THIS RETURNS A VALUE
let userLongitude = self.locationManager.location?.coordinate.longitude //THIS RETURNS A VALUE
print("User Location is ", userLatitude, ", " ,userLongitude)
let userLocation = CLLocation(latitude: userLatitude!, longitude: userLongitude!)
// event location
let eventLatitude = self.placemarkLatitude // THIS RETURNS 0.0
let eventLongitude = self.placemarkLatitude // THIS RETURNS 0.0
print("Event Location is ", eventLatitude, ", " ,eventLongitude)
let eventLocation = CLLocation(latitude: eventLatitude, longitude: eventLongitude)
//Measuring my distance to my buddy's (in km)
let distance = userLocation.distanceFromLocation(eventLocation) / 1000
//Display the result in km
print("The distance to event is ", distance)
if (distance < 100) {
print("yay")
}
}
}
你对异步问题是正确的。基本上,在此代码之后您无法执行任何操作:
// [A1]
self.geocoder.geocodeAddressString(combinedAddress, completionHandler: {
(placemarks, error) -> Void in
// [B] ... put everything _here_
})
// [A2] ... nothing _here_
原因是花括号(B)内的东西比它外面的东西发生得晚(包括之后的东西,A2)。换句话说,我上面的示意图中的代码按照A1,A2,B的顺序运行。但是你依赖于花括号内部发生的事情,所以你需要那个依赖代码在花括号里面,这样它就能按顺序执行与地理编码的结果。
当然这也意味着周围的函数不能返回结果,因为它在花括号中的东西发生之前就会返回。我的原理图中的代码为A1,A2,返回! B发生后才发生。很明显,你不能返回B中发生的任何事情,因为它还没有发生。
只需将从completionHandler获取的坐标值传递给任何其他方法,然后执行您想要执行的操作。
{
self.placemarkLatitude = (placemark.location?.coordinate.latitude)! //THIS RETURNS A VALUE
self.placemarkLongitude = (placemark.location?.coordinate.longitude)! //THIS RETURNS A VALUE
// After this code pass the values like,
passingTheCoordinates(placemarkLatitude, placemarkLongitude)
}
func passingTheCoordinates(latitude:CLLocationDegrees, _ longitude:CLLocationDegrees){
}
没有足够的声誉回复你的问题,但我今天也有同样的问题。我不太了解你的应用程序设计,但对于我的情况(与你一样卡在同一个地方,同样的功能,同样的问题,无法保存到变量)。我的解决方案(可能有点暂时,并不好)是将(placemark.location?.coordinate.latitude)!
和(placemark.location?.coordinate.longitude)!
保存为CoreData为Double。这就是我实现它的方式。正如我之前所说,由于我不太了解您的应用程序,所以您可能需要其他东西。
LocationManager.sharedInstance.getReverseGeoCodedLocation(address: searchBar.text!, completionHandler: { (location:CLLocation?, placemark:CLPlacemark?, error:NSError?) in
if error != nil {
print((error?.localizedDescription)!)
return
}
if placemark == nil {
print("Location can't be fetched")
return
}
//Saving geo code to Core Data
newEntry.lat = (placemark?.location?.coordinate.latitude)!
newEntry.long = (placemark?.location?.coordinate.longitude)!
})
感谢this repo获取LocationManager.swift文件