1. 程式人生 > >IOS 後臺不斷網處理

IOS 後臺不斷網處理

rcu link ica onf ash eat mov strac ack

IOS 後臺不斷網處理 收藏 Snaiper
  • 發表於 1年前
  • 閱讀 34
  • 收藏 0
  • 點贊 1
  • 評論 0

破譯“粽”子代碼,拿最高懸賞!>>> 技術分享

摘要: IOS 後臺不斷網處理

後臺不斷網處理 地圖服務

//

// 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 = [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 後臺不斷網處理