本文共 6294 字,大约阅读时间需要 20 分钟。
后台长时间运行除了官方的音乐,下载,定位,可以通过推送。
//============================
- (void)applicationDidEnterBackground:(UIApplication *)application { UIApplication* app = [UIApplication sharedApplication]; __block UIBackgroundTaskIdentifier bgTask; bgTask= [app beginBackgroundTaskWithExpirationHandler:^{ dispatch_async(dispatch_get_main_queue(),^{ if(bgTask != UIBackgroundTaskInvalid){ bgTask = UIBackgroundTaskInvalid; } }); }]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{ dispatch_async(dispatch_get_main_queue(), ^{ if(bgTask != UIBackgroundTaskInvalid){ bgTask= UIBackgroundTaskInvalid; } }); }); }
以上的方法似乎只有连接电脑测试时,能运行10分钟以上,如果不连接电脑在手机上运行则只能运行三分钟;
//=====================
下面是用定位的方法,把用时定位(需要设置info.plist),持续定位(需要设置info.plist),后台定位(需要设置self.locationManager.allowsBackgroundLocationUpdates=YES,也需要
同时还需要打开后台定位模式 -->点击项目-->Capabilitys-->Background Modes-->勾选Location update
)
程序进入后台有5秒中的缓冲时间来做一些事情,比如申请执行后台任务;
@interface AppDelegate () <LoginDelegate,CLLocationManagerDelegate>
@property(nonatomic,assign)UIBackgroundTaskIdentifier bgTask;//用于申请后台时间
@end
@implementation AppDelegate
//后台时间设置
-(void)backGroundTime{
UIApplication *appl=[UIApplication sharedApplication];
self.bgTask = [appl beginBackgroundTaskWithExpirationHandler:^{//注册一个后台任务,如果超过10分钟,就会执行这个block中的方法,而且这个block中必须要加上endBackgroundTask:方法,否则会crash;
只要调用了beginBackgroundTaskWithExpirationHandler:方法,就必须在handler里相应地调用endBackgroundTask:方法。
// //后执行这里,应该进行一些清理工作,如断开和服务器的连接等
[appl endBackgroundTask:self.bgTask];
self.bgTask =UIBackgroundTaskInvalid;
}];
}
//10分钟没到又打开app,结束后台任务
-(void)endBackGroundTask{
// 如果没到10分钟又打开了app,结束后台任务
if (self.bgTask!=UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication]endBackgroundTask:self.bgTask];
self.bgTask =UIBackgroundTaskInvalid;
}
}
//定时器到一定时间,关闭之前后台任务,开启新的后台任务
-(void)counst{
if (self.count %160 == 0) {
NSLog(@"结束之前的任务,又开启一个新任务");
[selfbackGroundTime];//又一次执行后台任务
}
NSLog(@"后台定时器-%tu--",self.count++);
}
//程序进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application {
[selfbackGroundTime];
_time=[NSTimerscheduledTimerWithTimeInterval:1target:self
selector:@selector(counst)userInfo:nilrepeats:YES];
[[NSRunLoopcurrentRunLoop]addTimer:_timeforMode:NSRunLoopCommonModes];
}
//程序将要进入前台
- (void)applicationWillEnterForeground:(UIApplication *)application {
发送开启socket重连的通知
[[NSNotificationCenterdefaultCenter]postNotificationName:@"initSocket"
object:nil];
[selfendBackGroundTask];//结束后台任务
}
//程序变的活跃
- (void)applicationDidBecomeActive:(UIApplication *)application {
[_timeinvalidate];//停止定时器
}
//应用程序将要变成不活跃状态
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"程序将要变的不活跃");
}
//程序进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application {
[selfbackGroundTime];//开启后台任务
//==============================
NSLog(@"程序进入后台");
}
//程序将要进入前台
- (void)applicationWillEnterForeground:(UIApplication *)application {
发送开启socket重连的通知
[[NSNotificationCenterdefaultCenter]postNotificationName:@"initSocket"object:nil];
[selfendBackGroundTask];//结束后台任务
//程序进入前台,角标清零
[UIApplicationsharedApplication].applicationIconBadgeNumber=0;
NSLog(@"程序将要进入前台");
}
//程序变的活跃
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"程序变的活跃");
}
//程序将要终止
- (void)applicationWillTerminate:(UIApplication *)application {
// [self gotoLogin];//程序将要终止的时候调用登录按钮,这时候长时间锁屏后再打开程序会自动登录。
NSLog(@"程序将要终止");
}
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
returnUIInterfaceOrientationMaskAll;
}
//==============使用后台定位保持后台在线
//定位城市
-(void)locationCity{
if(![CLLocationManagerlocationServicesEnabled] || ([CLLocationManagerauthorizationStatus] ==kCLAuthorizationStatusDenied))//判断定位服务是否打开
{
UIAlertController *alertController=[UIAlertControlleralertControllerWithTitle:@""message:@"请打开定位服务"preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sure=[UIAlertActionactionWithTitle:@"确定"style:UIAlertActionStyleCancelhandler:^(UIAlertAction *_Nonnull action) {
}];
[alertController addAction:sure];
[[UIApplicationsharedApplication].keyWindow.rootViewControllerpresentViewController:alertControlleranimated:YEScompletion:nil];
return;
}
//1. 创建一个CLLocationManager对象
self.locationManager = [CLLocationManagernew];
//2. 请求授权 --> iOS8以后需要授权并配置plist键值
if ([UIDevicecurrentDevice].systemVersion.floatValue >=8.0) {
if ([self.locationManagerrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManagerrequestWhenInUseAuthorization];
NSLog(@"使用时定位");
}
}
// //ios8持续定位
// if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
// if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){
// [self.locationManager requestAlwaysAuthorization];
// NSLog(@"持续定位");
// }
// }
self.locationManager.pausesLocationUpdatesAutomatically=NO;//不自动停止定位
//iOS9后台定位
if ([UIDevicecurrentDevice].systemVersion.floatValue >=9.0) {
//allowsBackgroundLocationUpdates :允许后台位置更新
self.locationManager.allowsBackgroundLocationUpdates = YES;
NSLog(@"后台定位");
}
//3. 设置代理-->来获取用户定位的数据
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone;//距离选择器,设置任何情况下都定位
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//预期精度kCLLocationAccuracyBest//kCLLocationAccuracyKilometer
//4. 开始定位
[self.locationManagerstartUpdatingLocation];
NSLog(@"开始定位");
}
//定位的代理方法-
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
//locations : 包含了经纬度,速度等信息
NSLog(@"locations: %@", locations);
// CLLocation: 位置对象
CLLocation *location = locations.lastObject;
NSLog(@"location: %@", location);
/反地理编码
[selfgeocodeWithLocation:location];
}
//反地理编码
-(void)geocodeWithLocation:(CLLocation *)location{
//1. 创建Geocoder对象
CLGeocoder *geocoder = [CLGeocodernew];
//2.2 调用反地理编码方法
[geocoder reverseGeocodeLocation:locationcompletionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks,NSError *_Nullable error) {
//3.1 防错处理
if (placemarks.count ==0 || error) {
return;
}
//3.2 解析数据反地理编码,只会对应一个唯一的地址,所以不需要for循环
CLPlacemark *placemark = placemarks.lastObject;
//locality: 城市
if (placemark.locality) {
NSLog(@"---city----%@", placemark.locality);
self.cityName=placemark.locality;
} else {
//administrativeArea:行政区域
self.cityName=placemark.administrativeArea;
}
}];
}
转载地址:http://ewmgi.baihongyu.com/