美文网首页
ios获取定位服务

ios获取定位服务

作者: lhg_serven | 来源:发表于2016-08-12 16:03 被阅读1324次

Getting the User’s Location  ios官方文档:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW8

ios想要获取用户位置信息,就需要开启定位服务。开启定位之前,工程中需要导入苹果自带的#import CoreLocation/CoreLocation.h 框架。

定位有3种模式:基站定位,GPS定位,WiFi定位: 在工程Info.plist中加入UIRequiredDeviceCapabilities键 指定为数组 其中加入location-services 字符串或gps字符串 来指定定位的模式,不过也不用加入,一般定位都会默认了这几种方式,官方说明 If your iOS app uses location services but is able to operate successfully without them, don’t include the corresponding strings in theUIRequiredDeviceCapabilitieskey,意思就是 不需要你来加入了。这里只是提示一下。

开启定位:一定要在工程Info.plist加入NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription键 获取定位权限,说明获取定位的描述,这个会在你开启定位的时候系统自动弹出一个是否开启的提示框,提示说明定位描述。

首先得创建一个定位的实例

- (CLLocationManager*)locationManager{

if(_locationManager==nil) {

_locationManager= [[CLLocationManageralloc]init];

_locationManager.desiredAccuracy=kCLLocationAccuracyNearestTenMeters;//定位精度

_locationManager.distanceFilter=kCLLocationAccuracyHundredMeters;//定位更新距离

//_locationManager.allowsBackgroundLocationUpdates=YES;//UIBackgroundModes 设置了 "location" 一定要设置此为Yes

//_locationManager.pausesLocationUpdatesAutomatically=YES;//UIBackgroundModes 设置了 "location",为了省电提供的一种方式,yes 容许定位自动暂停,

_locationManager.delegate=self;

}

return_locationManager;

}

- (void)startUpdateLocation

{

// [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied

//检查定位是否开启

// iOS8以后需要申请地理搜索权限

if([CLLocationManagerlocationServicesEnabled]) {

if([self.locationManagerrespondsToSelector:@selector(requestAlwaysAuthorization)]) {

[self.locationManager  requestAlwaysAuthorization];

}else{

// 8.0以下版本,直接搜索地理位置

[self.locationManager  startUpdatingLocation];

}

}else{

UIAlertView*alter = [[UIAlertViewalloc]initWithTitle:@"提示"message:@"手机定位功能不正常,请检查手机是否正常"delegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil];

[altershow];

//[self.locationManager startUpdatingLocation];

}

}

//只要CLAuthorizationStatus 定位的状态发生改变就会调用这个方法 你在使用 app的过程中切换定位状态也还是会 调用这个方法

- (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status

{//significantLocationChangeMonitoringAvailable

if(status ==kCLAuthorizationStatusAuthorizedAlways) {

// iOS8.0以后,只有获取了权限,才能开始搜索地理位置

self.isLocationServiceOn=YES;

[self.locationManager startUpdatingLocation];

}elseif(status ==kCLAuthorizationStatusDenied){

//UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"定位没有开启!!!\n请到设置->隐私->位置\n中开启定位服务"preferredStyle:UIAlertControllerStyleAlert];

//UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:nil];

//[alert addAction:action1];

//[[[UIApplication sharedApplication].windows lastObject].rootViewController presentViewController:alert animated:YES completion:nil];

self.isLocationServiceOn=NO;

}else{

}

}

- (void)locationManager:(CLLocationManager*)manager

didUpdateLocations:(NSArray*)locations

{

//self.myHud.labelText = @"正在定位地理位置...";

//[self.myHud show:YES];

AppMgr*mgr = [AppMgrdefaultAppMgr];

CLLocation* loc = [locationslastObject];

mgr.originCoord= loc.coordinate;

//这里,查询百度地图的经纬度

NSDictionary* dict =BMKConvertBaiduCoorFrom(mgr.originCoord,BMK_COORDTYPE_GPS);

floatlatitude = [[mgrdecodeBase64FromString:[dictvalueForKey:@"y"]]floatValue];

floatlongitude = [[mgrdecodeBase64FromString:[dictvalueForKey:@"x"]]doubleValue];

mgr.baiduCoord=CLLocationCoordinate2DMake(latitude, longitude);

// mgr.baiduCoord = mgr.originCoord;

NSLog(@"origincoord latitude:%f, longitude:%f", mgr.originCoord.latitude, mgr.originCoord.longitude);

TLog(@"转换百度坐标:%lf,%lf",mgr.baiduCoord.longitude,mgr.baiduCoord.latitude);

//业务需要拿到定位城市,根据定位城市来下载项目数据包,为了保证一定能拿到城市所以这里需要在登陆的时候仅加载一次,以后的定位调用不能执行

if(!self.onlyDoOnce&&locations.count>0) {

self.onlyDoOnce=YES;

CLGeocoder*geocoder = [[CLGeocoderalloc]init];

[geocoderreverseGeocodeLocation:loccompletionHandler:^(NSArray*placemarks,NSError*error) {

if(error) {

//反地理编码错误

NSLog(@"反地理编码错误:%@",error);

mgr.currentCity= [[fmCityObjalloc]init];

}else{

//编码正确拿到城市开始加载城市的资源包

if(placemarks.count>0) {

CLPlacemark* mark = [placemarksfirstObject];

NSString*cityName = mark.locality;

if(!cityName) {

//四大直辖市的城市信息无法通过locality获得,只能通过获取省份的方法来获得(如果city为空,则可知为直辖市)

cityName = mark.administrativeArea;

}

NSString* city = [selfgetPriciseCityName:cityNamestateFlag:mark.administrativeArea];

NSLog(@"定位城市:%@", city);

//在这里确定当前城市的信息,名称,代码号

[selfcheckLocalState:city];

}

}

}];

}

}

- (void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)error

{

//定位失败了的情况且只在登陆的时候执行一次

if(error) {

self.isLocationServiceOn=NO;

NSLog(@"手机定位失败");

}

}

苹果官方给出了3中定位方式:并说明为了节省电池电量 需要开发者选择合适的定位方式,特别是后台模式的定位,开启定位(NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription)一般是不需要设定后台模式的,除非你app切换到后台后还需要传定位数据,如下图你开启了后台定位模式

Performance - 2.5.4    Your app declares support for location in the UIBackgroundModes key in your Info.plist file but does not have any features that require persistent location. Apps that declare support for location in the UIBackgroundModes key in your Info.plist file must have features that require persistent location.

苹果审核的时候,必须要说明你哪里用到了定位,且是用来干什么的(拍成视屏给苹果说明)才能通过审核,不然就会被拒。

1.标准的定位服务,可以获取到用户当前的定位位置信息.

    上面的代码就是标准的定位服务, 如果你是开启了后台定位模式即UIBackgroundModes 设置了 "location"/一定要设置_locationManager.allowsBackgroundLocationUpdates=YES;_locationManager.pausesLocationUpdatesAutomatically=YES,提交苹果审核时要说明后台模式的用处。

2.区域监测的定位方式,通过监测已经指定一些地理区域,来返回当前用户定位的地理位置信息。或则,检    测蓝牙区域,如果检测到当前位置有蓝牙服务,系统会返回用户当前定位的位置。

      这个一般是用在蓝牙方面,可以得到地理位置,地理定位都是用的其他2种定位方式 

3. 明显的位置变化定位方式,离上次位置,用户位置有一定的距离变化 例如 500 meters or more,就会返回定位位置信息。即使位置没有变化,它会每15分钟唤醒app 。

  这种方式的定位你就需要调用startMonitoringSignificantLocationChanges 而不是startUpdatingLocation且一定是NSLocationAlwaysUsageDescription的定位描述  官方代码

- (void)startSignificantChangeUpdates

{

// Create the location manager if this object does not

// already have one.

if (nil == locationManager)

locationManager = [[CLLocationManager alloc] init];

locationManager.delegate = self;

[locationManager startMonitoringSignificantLocationChanges];

}

如果想要停止 调用stopMonitoringSignificantLocationChanges  定位接受到的定位信息都在这个方法里面locationManager:didUpdateLocations:  定位失败了调用locationManager:didFailWithError:

注意:这种方式的定位是不需要设置后台模式,就可以后台拿到定位数据的 处理事务只有10s时间(如果想需要更多时间来处理你的业务用beginBackgroundTaskWithName:expirationHandler:(这个方法会让你有10分钟的时间来处理你的业务)) 即使你的app切换到后台了挂起了或者后台了,这种方式定位如果接受到定位消息会自动重新启动或唤醒app(官方说If your app is terminated either by a user or by the system, the system doesn’t automatically restart your app when new location updates arrive. A user must explicitly relaunch your app before the delivery of location updates resumes.The only way to have your app relaunched automatically is to use region monitoring or the significant-change location service.),只不过需要你在后台重新创建CLLocationManager手动重新开启定位startMonitoringSignificantLocationChanges  不过如果用户设置app后台刷新Background App Refresh 不开启的话 有定位消息来的通知的时候,系统就不会重新唤醒或重启app。Background App Refresh 不开启 即使在前台,这种方式的定位将接受不到定位消息。也就是 这种方式的定位要保证Background App Refresh 是开启的状态  获取后台刷新状态方法是backgroundRefreshStatusproperty of theUIApplicationclass.你可以在定位之前先判断下,然后给出提示。

其实后台定位模式,有很多优化的方式来节省电池的电量,可以查看官方文档。

相关文章

  • ios获取定位服务

    Getting the User’s Location ios官方文档:https://developer.app...

  • IOS后台定位以及位置上传方案

    IOS后台定位以及位置上传方案 iOS定位原理和使用建议 iOS后台持续定位并定时上传 iOS 通过定位获取常驻后...

  • ios 13获取不了BSSID

    iOS13 后 无法直接获取BSSID 需要先获取定位 之后才能获取 获取定位权限获取BSSID

  • iOS UITableView获取特定位置的cell

    iOS UITableView获取特定位置的cell

  • 定位及耗电

    iOS-GPS定位基础知识 iOS -GPS定位服务和地图应用是两套完全不同的API iOS7 的四种定位服务-G...

  • iOS 系统自带定位服务

    iOS 自带定位服务(原创) ps:本文粘贴自别处,只为学习记录~ 定位服务 iOS 7 提供了4种不同的途径进行...

  • 学习随记 - 定位服务

    1. IOS定位服务的开启与基本设置 1. 要想使用IOS中的定位服务首先需要包含头文件CoreLocation/...

  • iOS - 获取定位

    1.在页面引入所需类: 2.定位方法: 3.用到的方法(将空字段过滤掉):

  • RXJava 应用系列-场景2

    二、获取定位信息 场景描述: 首先使用GPS定位,如果定位失败使用IP定位从服务器获取。 问题分析: 此问题可以分...

  • 4.2 定位适配对接指南

    对接说明 1. 获取定位服务 1.1 服务初始化配置 定位服务只有在LocationManager_init方法成...

网友评论

      本文标题:ios获取定位服务

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