IOS 後臺不斷網處理

後臺不斷網處理  地圖服務 git

// sql

//  AppDelegate.m api

//  networkdemo 數據結構

// app

//  Created by siteview on 16/2/1. async

//  Copyright © 2016年 數據結構. All rights reserved. ide

// 函數

 

#import "AppDelegate.h" ui

#import this

 

 

@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。

我這裏有兩個辦法:

一、使用一個無聲的音頻文件,當app切換到後臺後就開始無限循環播放。這樣你的app就永遠在後臺活着了,你在後臺想作什麼,均可以。

二、循環向系統申請「任務時間片「,也能保證你的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 

相關文章
相關標籤/搜索