티스토리 뷰
iOS 4 에서부터 백그라운드 작업 기능을 도입했다.
백그라운드 작업 기능은 iOS 가 지원하는 방식, iOS 지원하지 않는 방식 2가지로 나뉜다.
1. iOS 지원하는 방식
백그라운드 지원 타입은 아래와 같다.
1) 오디오 재생 2) 장치의 위치 추적 3) VoIP 앱 지원 4) 뉴스 가판대 앱의 새로운 컨텐츠 다운로드 5) 외부 블루투스 장치와의 통신 6) 백그라운드에서 컨텐츠 가져오기 7) 푸시 알림과 함께 백그라운드에서 다운로드 시작하기 |
구현하려면 2가지를 따라야한다.
1) 프로젝트 파일 -> target -> Capabilities -> Background Modes On 설정
2) 프로젝트 파일 -> target -> Info -> + -> Required Background Modes 에서 배열 지정
Ex) 백그라운드에서의 음악 재생
기본적으로 앱에서는 AVAudioSessionCategorySoloAmbient 오디오 세션 카테고리를 이용한다.
이 옵션은 다른 오디오가 재생 중이면 해당 오디오 재생을 중단하고,
화면이 잠기거나 묵음 스위치를 묵음으로 설정하면 이 앱의 오디오가 묵음이 된다.
따라서 AVAudioSessionCategoryPlayback 으로 변경해줘야한다.
(AVAudioSessionCategoryAmbient 는 동시 재생을 허용한다.)
#import <AVFoundation/AVAudioSession.h>
#import <MediaPlayer/MediaPlayer.h>
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *activeError;
if (![session setActive:YES error:&activeError]) {
return;
}
NSError *categoryError;
if (![session setCategory:AVAudioSessionCategoryPlayback error:&categoryError]) {
return;
}
이후 오디오 플레이어를 초기화 하고 play 한다.
추가적으로 오디오 재생 중 화면이 잠겨도
현재 재생 중인 곡에 대한 정보를 잠금화면에 보여줄 수 있는 기능이 있다.
UIImage *lockImage = [UIImage imageNamed:@"album_image"];
MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:lockImage];
NSDictionary *mediaDict = @{
MPMediaItemPropertyTitle : @"BackgroundTask Audio",
MPMediaItemPropertyMediaType : @(MPMediaTypeAnyAudio),
MPMediaItemPropertyArtwork : artwork,
};
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:mediaDict];
[self becomeFirstResponder];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
MPNowPlayingInfoCenter 객체는 정상적으로 동작하기 위해서
오디오를 재생하는 뷰나 뷰 컨트롤러를 firstResponder 로 지정해줘야한다.
다음으로 앱에게 remote control 이벤트에 응답하라고 지시한다.
이렇게 하면 잠금 화면 상에 있는 컨트롤을 통해
델리게이트 메소드를 실행해 앱의 오디오 재생을 통제할 수 있다.
2. iOS 가 지원하지 않는 방식
백그라운드 모드의 apple 공식 명칭은 multitasking 이다.
요즘은 거의 모두 iOS 4 이상 단말이고 multitasking 을 지원할 것이라고 예상은 되지만,
[UIDevice currentDevice] 에 isMultitaskingSupported 라는 메소드가 있다.
이를 확인 후 동작시켜야한다.
백그라운드 모드에서 진행하던 작업을 완료하려면
이 태스크를 백그라운드에서 실행할 수 있음을 애플리케이션에게 통보해야한다.
만약, 태스크가 작업을 완료하는 데 10 ~ 15 분보다 더 오랜 시간이 걸린다면,
완료 전에 앱이 강제 종료될 가능성이 높다.
장치 상의 각 앱은 일정 시간을 할당받지만, OS 에서 자원이 부족하다고 판단할 경우 강제종료 될 수 있다.
따라서 이 태스크는 갑자기 종료하는 경우를 대비해야하고
앱이 다시 실행됐을 때 작업을 재개할 수 있어야한다.
일반적인 과정은 아래와 같다.
- 애플리케이션에 백그라운드 태스크 아이디를 요청한다. - 만료 처리자 ( 백그라운드 모드에 할당된 시간 모두 소비 & 앱이 너무 많은 자원을 사용한다고 판단해 앱 종료 시 호출 ) 로 실행할 블록을 지정한다. - background 에서 실행될 태스크 코드를 실행한다. - 시간 만료 시 태스크를 종료하고 백그라운드 태스크 아이디를 무효화한다. |
_bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
// 이 block 은 framework 의 main thread 에서 호출한다.
if(_bgTaskId == UIBackgroundTaskInvalid){
return;
}
[[UIApplication sharedApplication] endBackgroundTask:_bgTaskId];
_bgTaskId = UIBackgroundTaskInvalid;
}];
추가적으로
[[UIApplication sharedApplication] backgroundTimeRemaining] 을 이용하여
오래 걸리는 작업 중 백그라운드 태스크에 남아 있는 할당 시간을 확인할 수 있다.
시간 확인 후 적게 남았다면 백그라운드 작업에서 추가로 루프를 시작할 지 결정할 수 있다.
'iOS 개발 > iOS' 카테고리의 다른 글
[iOS] UIImage, CIImage, CGImage 의 차이점 (0) | 2016.11.25 |
---|---|
[iOS] KeyChain 을 이용한 데이터 보호 및 앱 간 공유 (0) | 2016.11.25 |
[iOS] Canonical Mapping composed, decomposed (한글 분해 현상 대응) (0) | 2016.11.22 |
[iOS] CoreData 의 기본적인 개념, 사용시점, 작동 방식 (2) | 2016.11.21 |
UIView 의 frame, bound 및 Point Contain, Point Convert (0) | 2016.11.16 |
- Total
- Today
- Yesterday
- Swift3
- dictionary
- CGImage
- NSManagedObjectContext
- Swift 3.0
- set
- Swfit
- coredata
- Arc
- NSManagedObject
- Swift
- 읽기 좋은 코드가 좋은 코드다
- HTTP
- ios
- AWS
- UIView
- workerThread
- NSManagedObjectModel
- optional
- docker
- Block
- CIImage
- RunLoop
- 꺼내먹어요
- applicationWillResignActive
- string
- delegate
- EffectiveObjectiveC
- Swift 3
- thread
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |