123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- //
- // AMapManager.swift
- // RainbowPlanet
- //
- // Created by 南鑫林 on 2019/3/27.
- // Copyright © 2019 南鑫林. All rights reserved.
- //
- import UIKit
- class AMapManager: NSObject {
- private static let _sharedInstance = AMapManager()
- private override init() {} // 私有化init方法
- typealias LocationModelBlock = (_ locationModel: AMapLocationModel) -> Void
- class func shared() -> AMapManager {
- return _sharedInstance
- }
- var locationModel = AMapLocationModel.shared().getLocationModel()
- public func initAMap() -> Void {
- AMapServices.shared().apiKey = kAMapAppKey
- requestLocation(isSoughSingleLocation: true, isAccurateSingleLocation: false) { [weak self] (locationModel) in
- self?.locationModel = locationModel
- }
- }
- private lazy var locationManager: AMapLocationManager = {
- // 注意: locationManager为该类的属性
- let locationManager = AMapLocationManager()
- locationManager.locatingWithReGeocode = true
- return locationManager
- }()
- /// 粗单次定位
- private func soughSingleLocation() {
- // 带逆地理信息的一次定位(返回坐标和地址信息)
- locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
- // 定位超时时间,最低2s,此处设置为2s
- locationManager.locationTimeout = 2
- // 逆地理请求超时时间,最低2s,此处设置为2s
- locationManager.reGeocodeTimeout = 2
- }
- /// 精准单次定位
- private func accurateSingleLocation() {
- // 带逆地理信息的一次定位(返回坐标和地址信息)
- locationManager.desiredAccuracy = kCLLocationAccuracyBest
- // 定位超时时间,最低2s,此处设置为10s
- locationManager.locationTimeout = 10
- // 逆地理请求超时时间,最低2s,此处设置为10s
- locationManager.reGeocodeTimeout = 10
- locationManager.distanceFilter = 10
- }
- private func isSoughAccurateSingle(isSoughSingleLocation:Bool = false, isAccurateSingleLocation:Bool = false) {
- //粗单次定位
- if isSoughSingleLocation {
- soughSingleLocation()
- }
- //精准单次定位
- if isAccurateSingleLocation {
- soughSingleLocation()
- }
-
- }
- /// 请求单次定位
- ///
- /// - Parameters:
- /// - isSoughSingleLocation:
- /// - isAccurateSingleLocation: 粗单次定位 默认不调用
- /// - locationModelBlock: 精准单次定位 默认不调用
- public func requestLocation(isSoughSingleLocation:Bool = false, isAccurateSingleLocation:Bool = false, locationModelBlock:@escaping LocationModelBlock) {
- //粗单次定位
- if isSoughSingleLocation {
- soughSingleLocation()
- }
- //精准单次定位
- if isAccurateSingleLocation {
- soughSingleLocation()
- }
- locationManager.requestLocation(withReGeocode: true, completionBlock: {[weak self] (location: CLLocation?, reGeocode: AMapLocationReGeocode?, error: Error?) in
- if let error = error {
- let error = error as NSError
- if error.code == AMapLocationErrorCode.locateFailed.rawValue {
- //定位错误:此时location和regeocode没有返回值,不进行annotation的添加
- NXLLog("定位错误:{\(error.code) - \(error.localizedDescription)};")
- return
- } else if error.code == AMapLocationErrorCode.reGeocodeFailed.rawValue
- || error.code == AMapLocationErrorCode.timeOut.rawValue
- || error.code == AMapLocationErrorCode.cannotFindHost.rawValue
- || error.code == AMapLocationErrorCode.badURL.rawValue
- || error.code == AMapLocationErrorCode.notConnectedToInternet.rawValue
- || error.code == AMapLocationErrorCode.cannotConnectToHost.rawValue {
- //逆地理错误:在带逆地理的单次定位中,逆地理过程可能发生错误,此时location有返回值,regeocode无返回值,进行annotation的添加
- NXLLog("逆地理错误:{\(error.code) - \(error.localizedDescription)};")
- } else {
- //没有错误:location有返回值,regeocode是否有返回值取决于是否进行逆地理操作,进行annotation的添加
- }
- }
- self?.locationModel = self?.savelocationModel(location: location, reGeocode: reGeocode)
- locationModelBlock(self?.locationModel ?? AMapLocationModel.shared().getLocationModel()!)
- })
- }
- /// 后台定位
- public func backgroundLocation() {
- locationManager.delegate = self
- locationManager.distanceFilter = 100
- //iOS 9(不包含iOS 9) 之前设置允许后台定位参数,保持不会被系统挂起
- locationManager.pausesLocationUpdatesAutomatically = false
- //iOS 9(包含iOS 9)之后新特性:将允许出现这种场景,同一app中多个locationmanager:一些只能在前台定位,另一些可在后台定位,并可随时禁止其后台定位。
- if UIDevice.current.systemVersion._bridgeToObjectiveC().doubleValue >= 9.0 {
- locationManager.pausesLocationUpdatesAutomatically = true
- }
- //开始持续定位
- locationManager.startUpdatingLocation()
- }
- /// 持续定位
- public func continuedLocation() {
- locationManager.delegate = self
- locationManager.distanceFilter = 100
- //iOS 9(包含iOS 9)之后新特性:将允许出现这种场景,同一app中多个locationmanager:一些只能在前台定位,另一些可在后台定位,并可随时禁止其后台定位。
- if UIDevice.current.systemVersion._bridgeToObjectiveC().doubleValue >= 9.0 {
- locationManager.pausesLocationUpdatesAutomatically = true
- }
- //开始持续定位
- locationManager.startUpdatingLocation()
- }
- /// 停止定位
- public func stopUpdatingLocation() {
- locationManager.stopUpdatingLocation()
- }
- public func savelocationModel(location: CLLocation!, reGeocode: AMapLocationReGeocode?) -> AMapLocationModel {
- if let location = location {
- NXLLog("location:\(location)")
- locationModel?.longitude = String(describing: location.coordinate.longitude)
- locationModel?.latitude = String(describing: location.coordinate.latitude)
- }
- if let reGeocode = reGeocode {
- NXLLog("reGeocode:\(reGeocode)")
- /// 国家
- locationModel?.country = reGeocode.country ?? ""
- /// 省份
- locationModel?.province = reGeocode.province ?? ""
- /// 市
- locationModel?.city = reGeocode.city ?? ""
- /// 区/县
- locationModel?.district = reGeocode.district ?? ""
- /// 街道
- locationModel?.street = reGeocode.street ?? ""
- /// 详细描述
- locationModel?.poiName = reGeocode.poiName ?? ""
- /// AOIName
- locationModel?.aoiName = reGeocode.aoiName ?? ""
- /// 编号
- locationModel?.number = reGeocode.number ?? ""
- /// 城市Code
- locationModel?.citycode = reGeocode.citycode ?? ""
- /// adcode
- locationModel?.adcode = reGeocode.adcode ?? ""
- /// 地址格式化
- locationModel?.formattedAddress = reGeocode.formattedAddress ?? ""
- }
- AMapLocationModel.shared().setLocationModel(locationModel: locationModel!)
- return locationModel!
- }
- }
- // MARK: - 持续定位/后台定位
- extension AMapManager: AMapLocationManagerDelegate {
- func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode?) {
- NXLLog("location:{lat:\(location.coordinate.latitude); lon:\(location.coordinate.longitude); accuracy:\(location.horizontalAccuracy);};");
- locationModel = savelocationModel(location: location, reGeocode: reGeocode)
- }
- }
|