从后台任务启动iOS 7中的位置管理器
在iOS 7中,应用程序似乎无法再从后台任务启动位置管理器(通过调用startUpdatingLocation) 在iOS6中,我使用了这里描述的方法:每n分钟运行一次后台位置更新。其想法是使用计时器运行后台任务,并在计时器触发时启动位置管理器。之后,关闭位置管理器并启动另一个后台任务从后台任务启动iOS 7中的位置管理器,ios,objective-c,ios7,core-location,cllocationmanager,Ios,Objective C,Ios7,Core Location,Cllocationmanager,在iOS 7中,应用程序似乎无法再从后台任务启动位置管理器(通过调用startUpdatingLocation) 在iOS6中,我使用了这里描述的方法:每n分钟运行一次后台位置更新。其想法是使用计时器运行后台任务,并在计时器触发时启动位置管理器。之后,关闭位置管理器并启动另一个后台任务 更新到iOS 7后,这种方法不再有效。启动Location Manager后,应用程序不会收到任何locationManager:didUpdateLocations。有什么想法吗 我找到了问题/解决方案。当启动
更新到iOS 7后,这种方法不再有效。启动Location Manager后,应用程序不会收到任何locationManager:didUpdateLocations。有什么想法吗 我找到了问题/解决方案。当启动位置服务并停止后台任务时,后台任务应该延迟停止(我用了1秒)。否则定位服务将无法启动。另外,位置服务应该保持开启几秒钟(在我的示例中是3秒钟) 另一个重要的注意事项是,iOS 7的最大后台时间现在是3分钟,而不是10分钟 于2016年10月29日更新 有一个cocoapod,允许每n秒以期望的位置精度获得背景位置更新
let manager = APScheduledLocationManager(delegate: self)
manager.startUpdatingLocation(interval: 170, acceptableLocationAccuracy: 100)
存储库还包含一个用Swift 3编写的示例应用程序
于2014年5月27日更新
目标C示例:
1) 在“.plist”文件中,将ui背景模式设置为“位置”
2) 在需要的任何位置创建ScheduledLocationManager的实例
@property (strong, nonatomic) ScheduledLocationManager *slm;
3) 设置它
self.slm = [[ScheduledLocationManager alloc]init];
self.slm.delegate = self;
[self.slm getUserLocationWithInterval:60]; // replace this value with what you want, but it can not be higher than kMaxBGTime
4) 实现委托方法
-(void)scheduledLocationManageDidFailWithError:(NSError *)error
{
NSLog(@"Error %@",error);
}
-(void)scheduledLocationManageDidUpdateLocations:(NSArray *)locations
{
// You will receive location updates every 60 seconds (value what you set with getUserLocationWithInterval)
// and you will continue to receive location updates for 3 seconds (value of kTimeToGetLocations).
// You can gather and pick most accurate location
NSLog(@"Locations %@",locations);
}
以下是ScheduledLocationManager的实现:
ScheduledLocationManager.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
@protocol ScheduledLocationManagerDelegate <NSObject>
-(void)scheduledLocationManageDidFailWithError:(NSError*)error;
-(void)scheduledLocationManageDidUpdateLocations:(NSArray*)locations;
@end
@interface ScheduledLocationManager : NSObject <CLLocationManagerDelegate>
-(void)getUserLocationWithInterval:(int)interval;
@end
我试过你的方法,但对我来说不起作用。你能给我看看你的密码吗
实际上,我在iOS 7中找到了解决位置服务问题的解决方案
在iOS 7中,您无法在后台启动位置服务。如果希望定位服务在后台继续运行,则必须在前台启动定位服务,定位服务将继续在后台运行
如果你像我一样,停止定位服务并在后台使用计时器重新启动,它在iOS 7中无法工作
有关更多详细信息,您可以观看WWDC 2013的前8分钟视频307:
更新:定位服务也可以在后台工作。请查看Github上发布的更新帖子和完整解决方案,以及解释详细信息的博客帖子。实现此功能的步骤如下:
在项目的info.plist中的“所需后台模式”的第0项中添加“应用程序注册位置更新”
在应用程序未完成启动时编写以下代码
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startFetchingLocationsContinously) name:START_FETCH_LOCATION object:nil];
从您希望开始跟踪的位置编写以下代码
[[NSNotificationCenter defaultCenter] postNotificationName:START_FETCH_LOCATION object:nil];
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate startUpdatingDataBase];
将以下代码粘贴到AppDelegate.m
#pragma mark - Location Update
-(void)startFetchingLocationsContinously{
NSLog(@"start Fetching Locations");
self.locationUtil = [[LocationUtil alloc] init];
[self.locationUtil setDelegate:self];
[self.locationUtil startLocationManager];
}
-(void)locationRecievedSuccesfullyWithNewLocation:(CLLocation*)newLocation oldLocation:(CLLocation*)oldLocation{
NSLog(@"location received successfullly in app delegate for Laitude: %f and Longitude:%f, and Altitude:%f, and Vertical Accuracy: %f",newLocation.coordinate.latitude,newLocation.coordinate.longitude,newLocation.altitude,newLocation.verticalAccuracy);
}
-(void)startUpdatingDataBase{
UIApplication* app = [UIApplication sharedApplication];
bgTask = UIBackgroundTaskInvalid;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^(void){
[app endBackgroundTask:bgTask];
}];
SAVE_LOCATION_TIMER = [NSTimer scheduledTimerWithTimeInterval:300
target:self selector:@selector(startFetchingLocationsContinously) userInfo:nil repeats:YES];
}
添加名为“LocationUtil”的类,并将以下代码粘贴到头文件中:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
@protocol LocationRecievedSuccessfully <NSObject>
@optional
-(void)locationRecievedSuccesfullyWithNewLocation:(CLLocation*)newLocation oldLocation:(CLLocation*)oldLocation;
-(void)addressParsedSuccessfully:(id)address;
@end
@interface LocationUtil : NSObject <CLLocationManagerDelegate> {
}
//Properties
@property (nonatomic,strong) id<LocationRecievedSuccessfully> delegate;
-(void)startLocationManager;
#导入
#进口
@协议位置成功接收
@可选的
-(void)Location ReceivedSuccessFullyWithNewLocation:(CLLocation*)newLocation oldLocation:(CLLocation*)oldLocation;
-(void)地址解析成功:(id)地址;
@结束
@接口位置util:NSObject{
}
//性质
@属性(非原子,强)id委托;
-(无效)职业经理人;
并将以下代码粘贴到LocationUtil.m中
-(void)startLocationManager{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setPausesLocationUpdatesAutomatically:YES]; //Utkarsh 20sep2013
//[locationManager setActivityType:CLActivityTypeFitness];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[locationManager startUpdatingLocation];
//Reverse Geocoding.
geoCoder=[[CLGeocoder alloc] init];
//set default values for reverse geo coding.
}
//for iOS<6
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//call delegate Method
[delegate locationRecievedSuccesfullyWithNewLocation:newLocation oldLocation:oldLocation];
NSLog(@"did Update Location");
}
//for iOS>=6.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *newLocation = [locations objectAtIndex:0];
CLLocation *oldLocation = [locations objectAtIndex:0];
[delegate locationRecievedSuccesfullyWithNewLocation:newLocation oldLocation:oldLocation];
NSLog(@"did Update Locationsssssss");
}
-(无效)startLocationManager{
locationManager=[[CLLocationManager alloc]init];
locationManager.delegate=self;
[locationManager设置PausesLocationUpdates自动:是];//Utkarsh 20sep2013
//[locationManager setActivityType:ClaActivityTypeFitness];
locationManager.distanceFilter=KCLDistanceFilterOne;
locationManager.desiredAccuracy=KCallocationAccuracyBestforNavigation;
[locationManager startUpdatingLocation];
//反向地理编码。
地理编码器=[[CLGeocoder alloc]init];
//设置反向地理编码的默认值。
}
//对于iOS=6。
-(无效)位置管理器:(CLLocationManager*)管理器更新位置:(NSArray*)位置{
CLLocation*newLocation=[locations objectAtIndex:0];
CLLocation*oldLocation=[locations objectAtIndex:0];
[代表位置ReceivedSuccessFullyWithNewLocation:newLocation oldLocation:oldLocation];
NSLog(@“已更新位置”);
}
这似乎不起作用,很难理解getUserLocationWithInterval
从未被调用?请发布一个工作示例。是否在应用程序委托中创建实例?您好,我在使用上述示例代码-[\uu NSDictionaryI applicationdidebecomeactive:]:无法识别的选择器已发送到实例0x14db5cf0
请给出一些相关说明:)这非常有效,只需节省我的研发时间。谢谢您的帮助,+1:)谢谢发布此解决方案@sash@AskeAnker当您进行发布版本生成时,后台进程将停止。您好,如何在前台启动定位服务?我也有同样的问题。谢谢。你好,Guerrix,你可以在这里看到我的完整解决方案@Ricky如果我们想获得位置更新,即使通过双击主屏幕将应用程序从后台删除,该怎么办?@Azhar我听说即使应用程序被删除,也可以发送位置更新(不在前台或后台)从iOS 7.1开始,但我还没有找到可靠的解决方案。你说定位服务必须在前台启动?如果在进入后台后,我必须每隔15分钟获取一次用户的位置怎么办?我的iPhone电池很高兴地同意苹果不让应用程序这样做的决定:)哪里定义了“开始位置”?
-(void)startLocationManager{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setPausesLocationUpdatesAutomatically:YES]; //Utkarsh 20sep2013
//[locationManager setActivityType:CLActivityTypeFitness];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[locationManager startUpdatingLocation];
//Reverse Geocoding.
geoCoder=[[CLGeocoder alloc] init];
//set default values for reverse geo coding.
}
//for iOS<6
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//call delegate Method
[delegate locationRecievedSuccesfullyWithNewLocation:newLocation oldLocation:oldLocation];
NSLog(@"did Update Location");
}
//for iOS>=6.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *newLocation = [locations objectAtIndex:0];
CLLocation *oldLocation = [locations objectAtIndex:0];
[delegate locationRecievedSuccesfullyWithNewLocation:newLocation oldLocation:oldLocation];
NSLog(@"did Update Locationsssssss");
}