CLLocation + Weather(Alamofire) 问题
Posted
技术标签:
【中文标题】CLLocation + Weather(Alamofire) 问题【英文标题】:CLLocation + Weather(Alamofire) issues 【发布时间】:2017-03-19 23:56:12 【问题描述】:我正在尝试使用 CLLocation 来捕获经度和纬度,然后使用 Alamofire 中的经度和纬度来获取天气。每次,经纬度都不会停止更新,天气数据也不会打印(如果你想查看这里的数据示例链接:http://forecast.weather.gov/MapClick.php?lat=37.33233141&lon=-122.0312186&FcstType=json)
class SampleViewController: UIViewController, CLLocationManagerDelegate
var locationManager:CLLocationManager!
var startLocation: CLLocation!
var isFetchingWeather = false
override func viewDidLoad()
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
override func viewDidAppear(_ animated: Bool)
getCurrentLocation()
func getCurrentLocation()
if CLLocationManager.locationServicesEnabled()
locationManager.startUpdatingLocation()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
var userLocation:CLLocation = locations[0]
if isFetchingWeather != false
print("user latitude = \(userLocation.coordinate.latitude)")
print("user longitude = \(userLocation.coordinate.longitude)")
let requestLink = "http://forecast.weather.gov/MapClick.php?lat=\(userLocation.coordinate.latitude)&lon=\(userLocation.coordinate.longitude)&FcstType=json"
print(requestLink)
Alamofire.request(requestLink).validate().responseJSON
response in
switch response.result
case .success(let data):
let json = JSON(data)
self.weatherData = json["data"].arrayValue
for weather in self.weatherData
let temp = weather["weather"].stringValue
self.weatherString.append(temp)
print (self.weatherString)
if self.startLocation == nil
self.startLocation = userLocation as! CLLocation
self.locationManager.stopUpdatingLocation()
case .failure(let error):
print(error)
else
print("is fetching weather is false")
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
print("Error \(error)")
谢谢。
【问题讨论】:
【参考方案1】:你真的不应该在你的位置委托中运行你的天气请求。相反,在 didUpdateLocations
委托中获取您的位置并将其保存到 var。接下来,调用stopUpdatingLocation()
,然后调用一个单独的函数来发出你的天气请求。像这样的:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
let newLocation = locations.last
//check accuracy and timestamp of location to make sure its not a cached/old location (if you don't care about accuracy or time, you can remove this check)
let timeDiff = newLocation?.timestamp.timeIntervalSinceNow
if timeDiff < 5.0 && (newLocation?.horizontalAccuracy)!<=self.accuracyNeeded
//stop updating location
self.locationManager.stopUpdatingLocation()
//set currentUserLocation
self.myLocation=newLocation?.coordinate
//call function to get weather
//remove delegate
self.locationManager.delegate = nil
【讨论】:
感谢+1!几乎一切正常——即使是经度和纬度的链接也在打印,但 alamofire 本身什么也没返回...... @rmp 该位置是否可能没有天气数据?还是您遇到错误?【参考方案2】:设置一个标志以指示您何时开始获取天气信息,如果设置了该标志,则不要调用 Alamofire 来获取天气信息。例如,您可以在声明 startLocation
的行之后声明类似的内容:
var isFetchingWeather = false
然后,在locationManagerdidUpdateLocations
首先检查isFetchingWeather
是否为假。如果没有,请返回。否则,获取天气信息。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
if isFetchingWeather
return
isFetchingWeather = true
// Do the actual weather fetching
当然,您可能希望在获得一些位置更新后实际获取天气,因为最初的位置可能不那么准确:)
【讨论】:
我试过了,并且在 else 部分的 if 语句中,我打印了一个说明它是错误的。我运行了应用程序,控制台不停地打印打印。 @法希姆 您第一次执行提取时是否将isFetchingWeather
设置为true
?您能否提供一个代码示例,以便我可以看到您在做什么?不看就知道你的代码是如何执行的有点困难:)
是的——抱歉花了这么长时间。不,我没有。让我用我运行 @Fahim 的代码更新我的问题中的代码。
在您更新的代码中,您似乎仅在 isFetchingWeather
不是 false
时才获取天气信息 - 这意味着您必须获取天气才能再次获取天气信息 :) 这不是它应该如何工作的.请参阅上面我的答案中的更新代码,了解您应该如何设置它。以上是关于CLLocation + Weather(Alamofire) 问题的主要内容,如果未能解决你的问题,请参考以下文章