//
|
// YYLocationManager.swift
|
// OKProject
|
//
|
// Created by alvin_y on 2020/5/29.
|
// Copyright © 2020 yangwang. All rights reserved.
|
//
|
|
import Foundation
|
import RxSwift
|
import RxCocoa
|
import AMapFoundationKit
|
import AMapLocationKit
|
import AMapSearchKit
|
import HandyJSON
|
|
struct YYPOIModel: HandyJSON {
|
|
/// 省
|
var province: String = ""
|
|
/// 城市
|
var city: String = ""
|
|
/// 区
|
var district: String = ""
|
|
/// 城市编码
|
var citycode: String = ""
|
|
/// 名称
|
var poiName: String = ""
|
|
/// 详细地址
|
var address: String = ""
|
|
/// 纬度
|
var latitude: Double = 0
|
|
/// 经度
|
var longitude: Double = 0
|
}
|
|
|
class YYLocationManager: NSObject {
|
|
static let shared = YYLocationManager()
|
private override init() { super.init() }
|
|
let myUserDefault = UserDefaults(suiteName: "LocationInfos")
|
|
/// 当前定位城市是否是开通城市
|
let isValidated = BehaviorRelay<Bool>(value: false)
|
|
/// 区
|
var district: String {
|
get {
|
return myUserDefault?.object(forKey: "com.yy.locationInfos.district") as? String ?? ""
|
}
|
|
set {
|
myUserDefault?.set(newValue, forKey: "com.yy.locationInfos.district")
|
myUserDefault?.synchronize()
|
}
|
}
|
|
/// 省
|
var province: String {
|
get {
|
return myUserDefault?.object(forKey: "com.yy.locationInfos.province") as? String ?? ""
|
}
|
|
set {
|
myUserDefault?.set(newValue, forKey: "com.yy.locationInfos.province")
|
myUserDefault?.synchronize()
|
}
|
}
|
|
/// 当前城市
|
var currentCity: String {
|
get {
|
return myUserDefault?.object(forKey: "com.yy.locationInfos.currentCity") as? String ?? ""
|
}
|
|
set {
|
myUserDefault?.set(newValue, forKey: "com.yy.locationInfos.currentCity")
|
myUserDefault?.synchronize()
|
}
|
}
|
|
/// 当前城市经度
|
var latitude: Double {
|
get {
|
return myUserDefault?.double(forKey: "com.yy.locationInfos.latitude") ?? 0
|
}
|
|
set {
|
myUserDefault?.set(newValue, forKey: "com.yy.locationInfos.latitude")
|
myUserDefault?.synchronize()
|
}
|
}
|
|
/// 当前城市经度
|
var longitude: Double {
|
get {
|
return myUserDefault?.double(forKey: "com.yy.locationInfos.longitude") ?? 0
|
}
|
|
set {
|
myUserDefault?.set(newValue, forKey: "com.yy.locationInfos.longitude")
|
myUserDefault?.synchronize()
|
}
|
}
|
|
/// 当前城市id
|
var id: Int {
|
get {
|
return myUserDefault?.integer(forKey: "com.yy.locationInfos.id") ?? 0
|
}
|
|
set {
|
myUserDefault?.set(newValue, forKey: "com.yy.locationInfos.id")
|
myUserDefault?.synchronize()
|
}
|
}
|
|
/// 当前城市代码
|
var currentCityCode: String {
|
get {
|
return myUserDefault?.object(forKey: "com.yy.locationInfos.currentCityCode") as? String ?? ""
|
}
|
|
set {
|
myUserDefault?.set(newValue, forKey: "com.yy.locationInfos.currentCityCode")
|
}
|
}
|
|
private lazy var locationManager = AMapLocationManager()
|
private lazy var searchAPI: AMapSearchAPI = { [unowned self] in
|
|
let searchAPI = AMapSearchAPI()
|
searchAPI!.delegate = self
|
|
return searchAPI!
|
}()
|
|
var location: CLLocation?
|
lazy var searchPOISubject = PublishSubject<RequestStatus>()
|
|
/// 单次定位请求
|
///
|
/// - Parameters:
|
/// - success: 请求成功返回MMPOIModel类型的结果
|
/// - failure: 请求失败返回Error类型的错误
|
func requestLocation(success: @escaping (_ response: YYPOIModel) -> Void, failure: @escaping (_ error: Error) -> Void) {
|
locationManager.delegate = self
|
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
|
locationManager.locationTimeout = 2
|
locationManager.reGeocodeTimeout = 2
|
|
locationManager.requestLocation(withReGeocode: true) { [unowned self] (location, locationReGeocode, error) in
|
|
if let error = error {
|
|
failure(error)
|
}
|
|
if let location = location {
|
self.location = location
|
|
}
|
|
if let locationReGeocode = locationReGeocode {
|
if locationReGeocode.city == nil {
|
return
|
}
|
var model = YYPOIModel()
|
model.province = locationReGeocode.province
|
model.city = locationReGeocode.city
|
model.district = locationReGeocode.district
|
model.poiName = locationReGeocode.poiName
|
model.address = locationReGeocode.formattedAddress
|
model.citycode = locationReGeocode.adcode
|
if let location = location {
|
model.latitude = location.coordinate.latitude
|
model.longitude = location.coordinate.longitude
|
}
|
|
success(model)
|
}
|
|
}
|
}
|
|
/// 搜索附近
|
///
|
/// - Parameter keyword: 需要搜索的关键字
|
func searchAroundBy(keyword: String?) {
|
|
// guard let location = location else { return }
|
|
let searchRequest = AMapPOIKeywordsSearchRequest()
|
|
// searchRequest.location = AMapGeoPoint.location(withLatitude: CGFloat(location.coordinate.latitude), longitude: CGFloat(location.coordinate.longitude))
|
searchRequest.requireExtension = true
|
searchRequest.keywords = keyword
|
|
searchAPI.aMapPOIKeywordsSearch(searchRequest)
|
searchPOISubject.onNext(.loading)
|
|
}
|
|
func searchPOIAroundBy(latitude: CGFloat, longitude: CGFloat) {
|
|
let request = AMapPOIAroundSearchRequest()
|
request.location = AMapGeoPoint.location(withLatitude: latitude, longitude: longitude)
|
request.sortrule = 0
|
request.requireExtension = true
|
searchAPI.aMapPOIAroundSearch(request)
|
searchPOISubject.onNext(.loading)
|
}
|
}
|
|
|
extension YYLocationManager: AMapSearchDelegate {
|
|
/// 搜索附近完成的回调
|
///
|
/// - Parameters:
|
/// - request: 高德地图兴趣点搜索的请求对象
|
/// - response: 搜索结果
|
func onPOISearchDone(_ request: AMapPOISearchBaseRequest!, response: AMapPOISearchResponse!) {
|
|
let pois = response.pois as [AMapPOI]
|
|
let result = pois.map { (poi) -> YYPOIModel in
|
var myModel = YYPOIModel()
|
myModel.city = poi.city
|
myModel.poiName = poi.name
|
myModel.address = poi.address
|
myModel.latitude = Double(poi.location.latitude)
|
myModel.longitude = Double(poi.location.longitude)
|
return myModel
|
}
|
|
self.searchPOISubject.onNext(.success(result))
|
}
|
}
|
|
|
extension YYLocationManager: AMapLocationManagerDelegate{
|
func amapLocationManager(_ manager: AMapLocationManager!, doRequireLocationAuth locationManager: CLLocationManager!) {
|
locationManager.requestAlwaysAuthorization()
|
}
|
func amapLocationManager(_ manager: AMapLocationManager!, didChange status: CLAuthorizationStatus) {
|
}
|
func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
|
}
|
func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) {
|
|
}
|
}
|