需求说明
1、获取定位的逻辑与天气一致,先用GPS,无权限则使用ip定位
2、切换地理位置且从后台进入前台时会重新刷新一次数据
3、重新定位的时间间隔为15分钟。
具体实现逻辑
下面为获取GPS定位的方法。当获取到定位信息后存在一个全局变量中,并发出一个通知。
yywCurrentLocationString ,当需要使用时直接获取该字符串。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.count > 0 {
manager.stopUpdatingLocation()
//获取经纬度
guard let locationInfo = locations.last else {
return
}
// 定位需要转换成中文,先把系统设置换成中文
UserDefaults.standard.set(["zh-hans"], forKey: "AppleLanguages")
geocoder.reverseGeocodeLocation(locationInfo, completionHandler: { (placemarks, error) in
defer {
NotificationCenter.default.post(name: Notification.Name(rawValue: "updateLocation"), object: nil)
}
guard error == nil else {
return
}
guard let placeM = placemarks?.first else {
return
}
// print("placeM :\(placeM)")
// print("placeM.administrativeArea: \(String(describing: placeM.administrativeArea))")
// print("placeM.subAdministrativeArea: \(String(describing: placeM.subAdministrativeArea))")
// print("placeM.locality :\(String(describing: placeM.locality))")
// print("placeM.subLocality :\(String(describing: placeM.subLocality))")
// print("placeM.thoroughfare:\(String(describing: placeM.thoroughfare))")
// print("placeM.subThoroughfare:\(String(describing: placeM.subThoroughfare))")
//因为信息可能会存在多种组合的情况,所有有很多判断。
if placeM.locality != nil && placeM.administrativeArea == nil {
self.current_city = (placeM.locality)! + "," + (placeM.locality)!
if placeM.subLocality != nil {
yywCurrentLocationString = self.current_city + "," + (placeM.subLocality)!
} else if placeM.thoroughfare != nil {
yywCurrentLocationString = self.current_city + "," + (placeM.thoroughfare)!
} else {
yywCurrentLocationString = self.current_city
}
NotificationCenter.default.post(name: Notification.Name(rawValue: "updateLocation"), object: nil)
}
if placeM.locality == nil && placeM.administrativeArea != nil {
self.current_city = (placeM.administrativeArea)! + "," + (placeM.administrativeArea)!
if placeM.subLocality != nil {
yywCurrentLocationString = self.current_city + "," + (placeM.subLocality)!
} else if placeM.thoroughfare != nil {
yywCurrentLocationString = self.current_city + "," + (placeM.thoroughfare)!
} else {
yywCurrentLocationString = self.current_city
}
NotificationCenter.default.post(name: Notification.Name(rawValue: "updateLocation"), object: nil)
}
if placeM.locality != nil && placeM.administrativeArea != nil {
self.current_city = placeM.administrativeArea! + "," + (placeM.locality)!
if !self.current_city.contains("市") {
//let range = self.current_city.rangeOfString("市")
//self.current_city.removeRange(range!)
self.current_city = self.current_city + "市"
}
if placeM.subLocality != nil {
yywCurrentLocationString = self.current_city + "," + (placeM.subLocality)!
} else if placeM.thoroughfare != nil {
yywCurrentLocationString = self.current_city + "," + (placeM.thoroughfare)!
} else {
yywCurrentLocationString = self.current_city
}
}
DispatchQueue.main.async(execute: {
withExtendedLifetime(self.current_city) {
if self.current_city != nil{//保存定位信息
WeatherTool.getWeatherInfo(self.current_city)
}
}
// 定位需要转换成中文,最后把系统设置还原
UserDefaults.standard.set(IndexHeaderViewUX.userDefaultLanguages, forKey: "AppleLanguages")
})
})
}
如果GPS权限被关闭,则会使用IP进行获取定位。
class func getWeatherWithFromIP() {
let urlString = "http://api.114la.com/ip"//.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
guard let url = URL(string: urlString) else { return }
let session = URLSession.shared
let task = session.dataTask(with: url, completionHandler: { (data, response, error) in
defer {
DispatchQueue.main.async {
NotificationCenter.default.post(name: Notification.Name(rawValue: "updateLocation"), object: nil)
}
}
guard error == nil else {
print("getWeatherWithFromIP_ERROR->\(String(describing: error))")
return
}
guard let data = data else {
return
}
let enc = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(CFStringEncodings.GB_18030_2000.rawValue))
var provinceStr = "北京市"
var cityStr = "北京市"
let responseStr = NSString(data: data, encoding: enc)
if responseStr != nil {
if let strArr = responseStr?.components(separatedBy: "\""), strArr.count > 7 {
// for (index, item) in strArr!.enumerate() {
// print("index: \(index) item: \(item)")
// }
let pStr = strArr[5]
if pStr.hasPrefix("北京") ||
pStr.hasPrefix("重庆") ||
pStr.hasPrefix("天津") ||
pStr.hasPrefix("上海") {
provinceStr = pStr + "市"
} else {
provinceStr = pStr + "省"
}
let cStr = strArr[7]
cityStr = cStr + "市"
let cityName = provinceStr + "," + cityStr
//保存定位信息
yywCurrentLocationString = cityName
getWeatherInfo(cityName)
}
}
// print("responseStr :\(responseStr)")
})
task.resume()
}
在打开经验说明书等链接或部分接口时,会判断URL中是否有location参数。
如果没有则添加在URL后面当参数,服务端会根据location字段控制是否返回广告数据。