iOS 4.0이후로 Background Task 기능이 지원되며, 

시간은 최대 10분간이다.


대표적인 Background 관련 application delegate 는 아래와 같다.


applicationWillEnterForeground: 

applicationDidBecomeActive:

applicationWillResignActive:

applicationDidEnterBackground:


이중에서 applicationDidEnterBackgroun에 델리게이트에서 코드를 작성하면, 

앱이 백그라운드로 갔을 때, 

델리게이트에 작성이 된 코드를 처리를 한 이후에 메인스래드가 Suspended 상태로 전환이 된다.


이곳에서 아래의 코드를 확인하면 알 수가 있다.


- (void)applicationDidEnterBackground:(UIApplication *)application

{

while(YES) 

{

     [NSThread sleepForTimeInterval:0.3];

     NSLog(@"It's working in the background.");

}

}




하지만 위와 코드를 작성하면 두 가지 문제가 있다.

- 동작중에 Background 상태가 종료될 경우에 대한 처리를 할 수 없다.

- 델리게이트에 있는 코드 수행이 끝나면 바로 Suspend 상태로 전이가 된다.


그리하여 iOS 4.0부터 제공되는 메소드가 있다.


- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler
 

위의 메소드를 이용하면 앱이 백그라운드로 진입했을 때, 정지되지 않고 최대 10분간 동작 상태를 유지할 수 있다.


이하 구현 코드이다.


UIBackgroundTaskIdentifier bgTask;

bgTask = [application beginBackgroundTaskWithExpirationHandler:^{

        // 이 곳에 백그라운드 작업이 종료되기 직전에 호출되는 Block 이다.

        // 이 곳까지 진입했다는 것은 곧 종료됨을 의미한다. 이를 가정해야한다.

        [application endBackgroundTask:bgTask];

        bgTask = UIBackgroundTaskInvalid;

    }];

 

- bgTask 클래스 멤버 변수를 선언하고, beginBackgroundTaskWithExpirationHandler 메소드로 얻은 BackgroundTaskID를 넣어준다. (BackgroundTaskID 를 통하여 작업 우선순위 내지 종료 처리를 관리할 수 있다.)

- 종료되기 직전에 호출되는 Block에는 Task를 초기화할 코드를 넣는다.

- [application endBackgroundTask] 메소드를 통하여 백그라운드 Task를 종료한다.




이제 프로세스는 백그라운드로 진입을 하더라도 최대 10분을 보장받고 종료전에 Block 안의 초기화 코드도 실행할 수 있게 되었다.


하지만 작업이 끝나더라도 별 문제없다면 10분간 유지된다는 문제가 있다.

이는 backgroundTaskID를 통해서 해결할 수 있다.


백그라운드에서 필요한 작업을 마쳤으면 10분간 유지할 필요없이, 바로 리턴이 되도록 하는 코드이다.


- (void)applicationDidEnterBackground:(UIApplication *)application

{

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{


        // 이곳에 긴 시간동안 동작할 코드를 넣는다.


        [application endBackgroundTask:bgTask];

        bgTask = UIBackgroundTaskInvalid;

    });

}

 

- background 에 진입을 하면, async로 블럭안의 코드가 동작을 한다.

- 블럭안의 코드 안에 [application endBackgroundTask] 가 있으므로, 블럭코드가 끝나는 시점에 곧바로 Background 가 종료되고 suspended 상태가 된다.




그외에 아래와 같은 기능이 있다.


- Finite-Length Task in Background 지원 여부 확인

UIDevice* device = [UIDevice currentDevice];

BOOL backgroundSupported = NO;

if ([device respondsToSelector:@selector(isMultitaskingSupported)])

   backgroundSupported = device.multitaskingSupported;

 


- Background 상태 유지 가능 시간얻기

[[UIApplication sharedApplication] backgroundTimeRemaining]; 





출처: http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

+ Recent posts