首页 > 代码库 > IOS 后台不断网处理
IOS 后台不断网处理
- 发表于 1年前
- 阅读 34
- 收藏 0
- 点赞 1
- 评论 0
破译“粽”子代码,拿最高悬赏!>>>
后台不断网处理 地图服务
//
// AppDelegate.m
// networkdemo
//
// Created by siteview on 16/2/1.
// Copyright ? 2016年 数据结构. All rights reserved.
//
#import "AppDelegate.h"
#import
@interface AppDelegate ()
{
CLLocationManager * locationManager;
}
@property (assign, nonatomic) UIBackgroundTaskIdentifier bgTask;
@property (strong, nonatomic) dispatch_block_t expirationHandler;
@property (assign, nonatomic) BOOL jobExpired;
@property (assign, nonatomic) BOOL background;
@end
@implementation AppDelegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error//当定位服务不可用出错时,系统会自动调用该函数
{
if ( [error code] == kCLErrorDenied ) {
//服务未打开
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations//当用户位置改变时,系统会自动调用,这里必须写一点儿代码,否则后台时间刷新不管用
{
CLLocation * loc = [locations lastObject];
float latitudeMe = loc.coordinate.latitude;
float longtitudeMe= loc.coordinate.longitude;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// __weak__typeof__(self) weakself = self;
__weak __typeof(&*self) weakSelf = self;
//
// __weak __typeof(&*self)weakSelf = self;
//
// // 我之前一直这么写的
// __weak __typeof(self) weakSelf = self;
// // 或者这么写
// __weak XxxViewController *weakSelf = self;
// // 或者这么写
// __weak id weakSelf = self;
//
UIApplication* app = [UIApplication sharedApplication];
self.expirationHandler = ^{
[app endBackgroundTask:weakSelf.bgTask];
weakSelf.bgTask = UIBackgroundTaskInvalid;
weakSelf.bgTask = [app beginBackgroundTaskWithExpirationHandler:weakSelf.expirationHandler];
weakSelf.jobExpired = YES;
while ( weakSelf.jobExpired )
{
//等待180s循环进程的结束;
[NSThread sleepForTimeInterval:1];
}
[weakSelf startBackgroundTask];
};
// [self monitorBateryStateInBackground];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
// Override point for customization after application launch.
return YES;
}
//进入后台之后执行的任务
- (void) startBackgroundTask
{
NSLog(@" 重新启动任务 ");
//开始长时间运行任务
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) , ^{
NSLog(@" 重新新启动任务");
int count = 0;
BOOL NoticeoBackground = false; //只通知一次标志位
BOOL FlushBackgroundTime = false; //只通知一次标志位
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
while ( self.background && !self.jobExpired )
{
//进入后台运行
[NSThread sleepForTimeInterval:1];
count++;
if( count > 2 ) //每60s进行一次开启定位,刷新后台
{
count = 0;
[locationManager startUpdatingLocation]; //60s之后开启位置服务
NSLog(@"开启位置服务");
[NSThread sleepForTimeInterval:1];
[locationManager stopUpdatingLocation];
NSLog(@"停止位置服务");
FlushBackgroundTime = false;
}
}
});
for( int i=0; i<100000; i++ )
{
NSString * pathString = @"http://pics.sc.chinaz.com/files/pic/pic9/201601/apic18410.jpg";
NSURL * url = [NSURL URLWithString:pathString];
NSURLRequest * request = [[NSURLRequest alloc] initWithURL:url cachePolicy:0 timeoutInterval:30000];
NSURLResponse * response = [[NSURLResponse alloc] init];
NSData * data = http://www.mamicode.com/[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
UIImage * image = [[UIImage alloc] initWithData:data];
NSLog(@"image: %@",image);
[NSThread sleepForTimeInterval:1];
}
}
- (void) monitorBateryStateInBackground
{
self.background = YES;
[self startBackgroundTask];
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
//进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application {
self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:self.expirationHandler];
NSLog(@"进入后台");
[self monitorBateryStateInBackground];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
//从后台进入前台
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
[locationManager stopUpdatingLocation];
self.background = NO;
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application‘s managed object context before the application terminates.
[self saveContext];
}
#pragma mark - Core Data stack
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.siteview.zemeng.networkdemo" in the application‘s documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"networkdemo" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"networkdemo.sqlite"];
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application‘s saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application‘s saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
@end
另外一个人的后台多任务
IOS系统本身支持多任务,但是苹果出于对电量的控制,当用户按下home键后,切到后台的app一般就被系统pend了;前面提到一般,就说明还有不一般的app,到底是什么类型的app,这里不做说明。如何让一般的app可以在后台永久的运行呢?办法就是将一般的app处理成苹果允许后台运行的“不一般”的app。
我这里有两个办法:
1、使用一个无声的音频文件,当app切换到后台后就开始无限循环播放。这样你的app就永远在后台活着了,你在后台想做什么,都可以。
2、循环向系统申请“任务时间片“,也能保证你的app就永远在后台活着。
对比而言,第二种办法较为妥当(第一种可能被来电或者其他播放软件打断)。下面是操作代码:
在你app的程序代理实现文件中添加红色显示的代码(验证下吧,添加个定时器,看看是不是切换到后台后永远跑着)
#import "MQLAppDelegate.h"
@interface MQLAppDelegate ()
//时间片标识begin
@property UIBackgroundTaskIdentifier newtaskID;
@property UIBackgroundTaskIdentifier oldtaskID;
//时间片标识end
@end
@implementation MQLAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//时间片标识begin
self.newtaskID = self.oldtaskID = UIBackgroundTaskInvalid;
//时间片标识end
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
//时间片标识begin
self.newtaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
if (self.newtaskID != UIBackgroundTaskInvalid && self.oldtaskID != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask: self.oldtaskID];
}
self.oldtaskID = self.newtaskID;
//时间片标识end
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
//时间片标识begin
if (self.oldtaskID != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask: self.oldtaskID];
self.oldtaskID = UIBackgroundTaskInvalid;
}
//时间片标识end
}
@end
IOS 后台不断网处理