ios获取定位服务

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.你可以在定位之前先判断下,然后给出提示。

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容