美文网首页
Swift 简易定位Demo(基于CLLocationManag

Swift 简易定位Demo(基于CLLocationManag

作者: YYYYYY25 | 来源:发表于2019-03-08 16:39 被阅读0次

这是一个简易的一次性定位工具的封装,基于系统CLLocationManager。如果项目中需要获取只是简单的获取定位信息,可以在这个demo的基础上进行扩展。

准备:

创建demo项目,并通过Storyboard添加如下图所示的两个button事件。
1 获取定位
2 判断定位功能是否可用


视图结构
创建定位单例:
import CoreLocation

class LocationManager: NSObject {
    static let sharedInstance = LocationManager()
    private override init() {}
}

声明一个用于管理定位操作的工具类,单例处理,并导入 Conre Location 框架。

初始化操作:
private let locationMgr = CLLocationManager() // 1

func config() {
    guard isLocationServiceEnabled() else { // 2
        return
    }
    
    let status  = CLLocationManager.authorizationStatus()

    // 用户没有决定是否使用定位服务
    if status == .notDetermined {
        locationMgr.requestWhenInUseAuthorization()
        return
    }
    
    locationMgr.delegate = self // 3
    locationMgr.desiredAccuracy = kCLLocationAccuracyBest
    locationMgr.distanceFilter = 1000.0
    locationMgr.startUpdatingLocation()
}

1 创建CLLocationManager对象,并用私有属性管理。(这里不能把CLLocationManager声明为config方法中的局部变量,因为超出作用域后,系统获取定位权限的弹窗会自动消失)
2 声明isLocationServiceEnabled方法,判断系统是否开通定位权限。

private func isLocationServiceEnabled() -> Bool {
    if CLLocationManager.locationServicesEnabled() {
        return true
    } else {
        return false
    }
}

3 实现CLLocationManagerDelegate协议

var city: String = "Undefault" 

extension LocationManager : CLLocationManagerDelegate {

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        locationMgr.stopUpdatingLocation()
        let currentLocation = locations.last
        let geoCoder = CLGeocoder()
        
        // let userdefault = UserDefaults.standard
        // let userDefaultLanguages = userdefault.object(forKey: "AppleLanguages")
        // userdefault.set(NSArray(objects: "zh-Hans-CN"), forKey: "AppleLanguages")

        geoCoder.reverseGeocodeLocation(currentLocation!) { (placemarks, error) in
            
            if (error != nil) {print("reverse geodcode fail:" +  "\(error?.localizedDescription ?? "")")}
            
            let placeMark = placemarks?.last
    
            if let cty = placeMark?.locality {
                self.city = cty
            }else {
                self.city = placeMark?.administrativeArea ?? "Undefault"
            }
            
            print(self.city)
            
        }
        
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Error \(error.localizedDescription)")
    }
}

PS:这里最开始添加的city属性用来临时存储定位成功后的信息,应该根据不同的项目需要存储定位信息。我只是用字符串简单的接收而已。
常规做法至少应该是通过获取的城市名称去服务器(或者本地plist)请求对应的cityId,通过ID的形式存储。

获取定位:
@IBAction func getLocation(_ sender: UIButton) {
    let mgr = LocationManager.sharedInstance
    mgr.config()
}

通过单例调用config方法,获取定位。
实际项目中,这个步骤大多发生在didFinishLaunchingWithOptions中。

检查定位权限:

在实际项目中,由于用户行为的多样,如果项目中的某些功能需要获取定位信息,那你需要提前进行检查。

func isLocationServiceSuccess(handler: (_ actions: [UIAlertController])->()) -> Bool {
    var arts = [UIAlertController]()
    if !isLocationServiceEnabled() { // 手机定位没开
        // 添加一个alertContrller 跳转手机定位设置
    }
    if !isLocationServiceOpen() { // app定位没开
        let alert = combineAlertController(title: "Location Services Disabled", message: "Please enable Location Services in Settings", open: UIApplication.openSettingsURLString)
        arts.append(alert)
    }
    if arts.count > 0 {
        handler(arts)
        return false
    }
    
    if city == "Undefault" { // 城市获取失败
        config()
    }
    return true
}

这个方法做了3件事:
1 判断手机是否开启定位服务,如果没开,则弹窗提示。
2 判断app是否开启定位服务,如果没开,则弹窗提示。
3 判断是否保存了正常的定位信息。
如果以上都通过,则表明检查成功,可以继续调用其他的功能。

PS:在这个方法中,由于会创建系统的UIAlertController进行弹窗提示,所以需要通过 block 把创建的弹窗对象向外传递。

调用方法:
@IBAction func check(_ sender: UIButton) {
    
    let mgr = LocationManager.sharedInstance
    let success = mgr.isLocationServiceSuccess { (alertControllers) in
        for ctrs in alertControllers {
            self.present(ctrs, animated: true, completion: nil)
        }
    }
    print(success)
}

创建LocationManager单例,并调用isLocationServiceSuccess方法。判断该方法返回值,继续下面的业务需求。

总结:

如果你不想过多的引用第三方库让你的项目臃肿不堪,那么很多小功能你都可以尝试自己实现一下。在这个过程中你可以对系统原生SDK有更多的了解,同时再此基础之上也更方便你去阅读优秀的源码。
我这个定位的demo十分简陋,只是提供一个思路给大家去完善。
DEMO

相关文章

网友评论

      本文标题:Swift 简易定位Demo(基于CLLocationManag

      本文链接:https://www.haomeiwen.com/subject/plurpqtx.html