Swift-Location 让定位变得如此简单

732
看看如此简单的使用方式吧
  • 仅一次定位
    // 在需要定位的地方先定位
    EPLocationManager.manager.aloneReGeocodeLocation()
    // 接下来就可以在需要的地方获取定位信息了
    if let model = EPLocationManager.manager.userLocationModel {
        picker.selectProvince(model.province, city: model.city, area: model.area)
    }
    
    
    // 或者也可以一步到位
    EPLocationManager.manager.aloneReGeocodeLocation { (model) in
        print("province:\(model.province), city:\(model.city), area:\(model.area)")
    }
  • 连续定位
// 启动连续定位
EPLocationManager.manager.serialReGeocodeLocation { (model) in
    print("province:\(model.province), city:\(model.city), area:\(model.area)")
}

// 记得在不需要定位时定位定位
EPLocationManager.manager.stopLocation()
那这个定位的实现是怎样?
import UIKit
import CoreLocation


class EPLocationManager: NSObject {

    @objc public static let manager: EPLocationManager = { EPLocationManager() }()
    
    private lazy var locationManager = CLLocationManager()
    private var locationCompletionBlock: ((EPLocationModel) -> ())?
    @objc public var userLocationModel: EPLocationModel? // 用户定位信息的模型
    private var isAloneLocaion: Bool=false


    private override init() {

        super.init()
        configLocationManager()
    }

    deinit {
        locationManager.delegate = nil
    }

    

    private func configLocationManager() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = kCLDistanceFilterNone
        locationManager.pausesLocationUpdatesAutomatically = false
        locationManager.requestWhenInUseAuthorization()
    }

    

    /// 停止定位
    func stopLocation() {
        locationManager.stopUpdatingLocation()
    }

    /// 单次定位
    @objc func aloneReGeocodeLocation(_ completionBlock: ((EPLocationModel) -> ())?=nil) {

        isAloneLocaion = true
        serialReGeocodeLocation(completionBlock)
    }

    /// 连续定位 记得在不用的时候调用 stopLocation
    func serialReGeocodeLocation(_ completionBlock: ((EPLocationModel) -> ())?=nil) {

        self.locationCompletionBlock = completionBlock
        locationManager.stopUpdatingLocation()
        locationManager.startUpdatingLocation()
        locationManager.startUpdatingHeading()
    }
}


extension EPLocationManager: CLLocationManagerDelegate {

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        for location in locations {
            HGLog("lat:\(location.coordinate.latitude); lon:\(location.coordinate.longitude); accuracy:\(location.horizontalAccuracy)m")
            if location.coordinate.latitude > 0 && location.coordinate.longitude > 0 {
                if isAloneLocaion { // 单次定位成功就停止定位
                    stopLocation()
                }
            }
           
            CLGeocoder().reverseGeocodeLocation(location) { (marks, error) in
                if error != nil {
                    HGLog("geocoder fail \(error!.localizedDescription)")
                }
                guard let placemarks = marks else { return }
                if placemarks.count > 0 {
                    let placemark = placemarks[0]
                    let model = EPLocationModel()
                    model.coordinate = location.coordinate
                    model.city = placemark.locality
                    model.province = placemark.administrativeArea
                    model.area = placemark.subLocality
                    model.address = placemark.name

                    /**

                     // 也可以
                     if let addressInfo = placemark.addressDictionary {

                         model.province = addressInfo["State"] as? String
                         model.city = addressInfo["City"] as? String
                         model.area = addressInfo["SubLocality"] as? String
                         model.address = addressInfo["name"] as? String
                     }

                     po placemark.addressDictionary
                     ▿ Optional<Dictionary<AnyHashable, Any>>
                           ▿ key : AnyHashable("Country")
                           - value : 中国
                           ▿ key : AnyHashable("Thoroughfare")
                           - value : 桃园路
                           ▿ key : AnyHashable("FormattedAddressLines")
                           ▿ value : 1 element
                             - 0 : 中国广东省深圳市罗湖区桃园路211号
                           ▿ key : AnyHashable("SubLocality")
                           - value : 罗湖区
                           ▿ key : AnyHashable("City")
                           - value : 深圳市
                           ▿ key : AnyHashable("Street")
                           - value : 桃园路211号
                           ▿ key : AnyHashable("State")
                           - value : 广东省
                           ▿ key : AnyHashable("Name")
                           - value : 桃园路211号
                           ▿ key : AnyHashable("SubThoroughfare")
                           - value : 211号
                           ▿ key : AnyHashable("CountryCode")
                           - value : CN
                     */

                    

                    self.userLocationModel = model
                    self.locationCompletionBlock?(model)
                }

                for placemark in placemarks {
                    HGLog("placemark:\(placemark.administrativeArea ?? "")-\(placemark.locality ?? "")-\(placemark.subLocality ?? "")-\(placemark.name ?? "")")

                }
            }
        }
    }

    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        HGLog("location is fail \(error.localizedDescription)")
    }

}




class EPLocationModel: NSObject {

    @objc var coordinate  : CLLocationCoordinate2D = CLLocationCoordinate2DMake(0, 0)
    @objc var adcode      : String?
    @objc var citycode    : String?
    @objc var city        : String?
    @objc var area        : String?
    @objc var province    : String?
    @objc var address     : String?
}