39

iOS开发之定位

 5 years ago
source link: http://www.cocoachina.com/ios/20190304/26463.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在iOS开发中,定位是很多App都需要使用的功能。本文主要对iOS中的定位知识点进行介绍。本文代码环境为:Xcode 10.1 + Swift 4.2。

一、模块与常见类

  • 定位所包含的类都在CoreLocation模块中,所以必须导入import CoreLocation

  • CLLocation:表示某个位置的地理信息,比如经纬度、海拔等

  • CLLocationManager:定位管理器,可以理解为定位不能自己工作,需要有个管理者对它进行全过程监督。

  • CLGeocoder:地理编码,分为两种

    • 正向地理编码:根据位置信息,获取具体的经纬度等信息

    • 反向地理编码:根据给定的经纬度等信息,获取位置信息

  • CLPlacemark:位置信息,包含的信息如国家、城市、街道等

  • CLLocationManagerDelegate:定位代理,不管是定位成功与失败,都会有相应的代理方法回调

  • 具体的工作流程

    (1)CLLocationManager发起定位,定位成功或者失败都会回调CLLocationManagerDelegate中相应的代理方法

    (2)在成功的代理方法中获取 CLLocation 对象,进而获取经纬度

    (3)通过 CLGeocoder获取经纬度对应的位置信息CLPlacemark

    (4)通过CLPlacemark获取具体的位置信息

二、权限

在iOS中,隐私保护特别好,凡事需要定位的时候,第一次必须弹出对话框给用户选择,一共有两种权限

  • 使用时才定位权限,使用这种,必须走两步

    (1)程序中发起 requestWhenInUseAuthorization

    (2)在info.plist对应的位置写明申请权限的具体原因

  • 一直可以定位权限,使用这种,也是两步

    (1)程序中发起 requestAlwaysAuthorization

    (2)在info.plist对应的位置写明申请权限的具体原因

ZbmMJjy.png!web

权限原因填写

注意:上架的App这个原因必须写明确

三、模拟器定位

由于定位需要GPS,所以一般情况下,都需要真机进行测试,笔者在教学过程中,经常使用的是一种模拟定位,这种定位需要准备一个gpx 的文件,可以取名 XXX.gpx,里面的内容如下:

<?xml version="1.0" encoding="UTF-8" ?><gpx version="1.1"
creator="GMapToGPX 6.4j - http://www.elsewhere.org/GMapToGPX/"
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">


<wpt lat="31.2906511800" lon="118.3623587000">
<name>安徽商贸职业技术学院name>
<cmt>中国安徽省芜湖市弋江区文昌西路24号 邮政编码: 241002cmt>
<desc>中国安徽省芜湖市弋江区文昌西路24号 邮政编码: 241002desc>
wpt>gpx>

将自己的定位信息填写进xml对应的位置即可,然后选择Edit Scheme,在Options中选择自己的gpx 的文件,这样模拟器运行的时候就会读取该文件的位置信息。

yiARJre.png!web

Edit Scheme

四、后台定位

如果你的App需要后台定位,可以这样做,首先在Capabilities中打开后台模式

eEZnAnA.png!web

后台模式

前面说过定位权限分两种,针对这两种情况,后台定位的代码不一样,效果也不一样

  • 使用时才定位权限需要加上locationManager.allowsBackgroundLocationUpdates = true

    开启后台定位,而一直可以定位权限不需要写任何额外代码

  • 使用时才定位权限退出后,手机顶部会有蓝条提示,而一直可以定位权限则没有

7juQveY.png!web

后台定位蓝条提醒

五、开发步骤与示例代码

  1. 导入CoreLocation模块

  2. 创建CLLcationManager对象,设置参数和代理,请求定位授权并配置info.plist

  3. 调用CLLcationManager对象的startUpdatingLocation方法进行定位

  4. 实现代理方法,在定位成功的方法中进行位置信息的处理

import UIKit
import CoreLocation

class ViewController: UIViewController {
//定位需要一个CLLocationManager
lazy var locationManager:CLLocationManager = CLLocationManager()

override func viewDidLoad() {
super.viewDidLoad()
setupManager()
}

func setupManager(){

//默认情况是这样的,每当位置改变时LocationManager就调用一次代理。通过设置distanceFilter可以实现当位置改变超出一定范围时LocationManager才调用相应的代理方法。这样可以达到省电的目的。
locationManager.distanceFilter = 300
//精度 比如为10 就会尽量达到10米以内的精度
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//代理
locationManager.delegate = self
//第一种:能后台定位但是会在顶部出现大蓝条(打开后台定位的开关)
//允许后台定位
locationManager.allowsBackgroundLocationUpdates = true
locationManager.requestWhenInUseAuthorization()
//第二种:能后台定位并且不会出现大蓝条
//locationManager.requestAlwaysAuthorization()

}

override func touchesBegan(_ touches: Set , with event: UIEvent?) {

//发起位置更新(定位)会一直轮询,耗电
self.locationManager.startUpdatingLocation()
}

}


extension ViewController : CLLocationManagerDelegate{

//定位成功
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

let location = locations.last
//地理编码的类
let gecoder = CLGeocoder()
if let location = location {
//反地理编码 转换成 具体的地址
gecoder.reverseGeocodeLocation(location) { (placeMarks, error) in
//CLPlacemark -- 国家 城市 街道
let placeMark = placeMarks?.first
if let placeMark = placeMark{
print("\(placeMark.country!) -- \(placeMark.name!) -- \(placeMark.locality!)")
}
}
}
self.locationManager.stopUpdatingLocation()
}

//定位失败
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)

}
}

六、代码运行效果

NF3QvaJ.gif

运行效果


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK