관리 메뉴

HAMA 블로그

[Swift 3.0] Background Mode 이해하기 본문

아이폰 (IOS)

[Swift 3.0] Background Mode 이해하기

[하마] 이승현 (wowlsh93@gmail.com) 2016. 12. 1. 15:16



iOS 개발을 시작하고나서 가장 궁금한 점이 App 이 백그라운드로 넘어 갔을때의 행위여서 이와 관련된 내용을 질문으로도 iOS 커뮤니티에 올려보았고 대답이 달리기전에  나도 무임승차 할 수는 없어서 조사를 해보았다. 참고로 질문 내용은 아래와 같다.


이번에 iOS 로 처음 앱개발을 해보는 중인데요.  (swift 3.0 기반) 

서버로 부터 메세지를 전달 받아서 (PUSH)  사용자에게 알려 주려고 합니다.

iOS 에서 제공하는 푸쉬서비스를 사용하지 않고 개발하려 하는데요.


일단 DispatchQueue.global 를 하나 만들고 그 안에서 서버와 커넥션을 맺은후 (TCP) 

서버로부터 데이터를 받으면 localnotification 을 통해서 사용자에게 알리는 형태입니다.


이게 앱이 전면에 있을 경우는 아주 잘 되지만 , 백그라운드로 넘어가면 멈추더군요. 
아마 iOS 정책이 그런듯 싶은데.. 


질문1. 백그라운드 넘어가서도 유지되는 쓰레드를  iOS 에서 구현 할 수 있는지요?

질문2. 보통 자신이 push 구현 할 때 어떻게 구현하나요? (백그라운드시에도 계속 서버와 연결되어 있어야 할텐데요)

질문3. 백그라운드 시는 무조건  APNS ,GCM, FCM 같은 것을 이용해야 하나요? 
질문4. 즉 나의 서버에서 직접 보내고 스마트폰에서 직접 받는 방식은 불가능한가요?( 핵심 질문)

질문5. 혹시 이러한 내용을 구현하기 위해 Background Modes 를 활성화 시켜서 사용하는지요? 




이 글은 아래의 글들을 참고,번역하여 작성되었다. (참고로 백그라운드 모드로 푸쉬 서비스를 대체 할 수는  없는 듯) 


백그라운드 실행이란 

스마트폰 사용자가 앱을 사용하지 않을 경우 시스템은 앱을 백그라운드 상태로 이동시킵니다. (홈버튼클릭) 많은 앱의 경우 백그라운드 상태는 일시 중지로 앱에 대한 간단한 중지입니다. 앱 일시 중지는 배터리 수명을 향상시키는 방법이기도 하므로 시스템에서 중요한 시스템 리소스를  사용자가 사용 해야하는 새로운 foreground 앱을 위해 할당합니다.

대부분의 앱은 정지 상태로 이전하면 그만이기도 하지만 앱이 백그라운드에서 계속 실행되는 정당한 이유도 있습니다. 하이킹 앱은 시간 경과에 따라 사용자의 위치를 ​​추적하여 하이킹지도 위에 해당 코스를 표시 할 필요가 있습니다. 오디오 앱은 잠금 화면에서 계속 음악을 재생해야 할 수 있습니다. 어떤 앱은 백그라운드에서 콘텐츠를 다운로드하여 해당 콘텐츠를 사용자에게 제공 할 때 지연을 최소화 할 수 있습니다. 앱을 백그라운드에서 실행하는 것이 필요하다고 판단되면 iOS는 시스템 리소스 또는 사용자 배터리를 소모하지 않고 효율적으로 수행 할 수 있도록 도와줍니다. iOS에서 제공하는 기술은 세 가지 범주로 나뉩니다.

* 포 그라운드에서 짧은 작업을 시작하는 앱은 앱이 백그라운드로 이동할 때 해당 작업을 완료 할 시간을 요청할 수 있습니다.

* 포 그라운드에서 다운로드를 시작하는 앱은 다운로드 관리를 시스템에 전달할 수 있으므로 다운로드가 계속되는 동안 앱이 일시 중지되거나 종료 될 수 있습니다. 

*특정 유형의 작업을 지원하기 위해 백그라운드에서 실행해야하는 앱은 하나 이상의 백그라운드 실행 모드에 대한 지원을 선언 할 수 있습니다.

사용자 경험을 향상 시키기 위해 반드시 필요한 경우가 아니라면 배경 작업을 하지 않도록 하십시오. 사용자가 다른 앱을 실행했거나 사용자가 기기를 잠그면 앱이 백그라운드로 이동할 수 있습니다. 두 경우 모두 사용자가 앱이 의미있는 작업을 수행 할 필요가 없다는 신호입니다. 이러한 조건에서 계속해서 실행되게하면 기기의 배터리가 소모되고 사용자가 앱을 완전히 종료 해버리게 만들 수 있습니다. 따라서 백그라운드에서하는 일에 유의하고 가능하면 피하십시오.

백그라운드 이동시 잠시의 추가시간을 요 하는 경우

앱이 작업 중간에 작업을 완료하는 데 약간의 시간이 필요할 경우 UIApplication 객체의 beginBackgroundTaskWithName : expirationHandler : 또는 beginBackgroundTaskWithExpirationHandler : 메서드를 호출하여 추가 실행 시간을 요청할 수 있습니다. 이 메소드 중 하나를 호출하면 일시적으로 앱 일시 중지가 지연되어 작업을 완료하는 데 약간의 시간이 소요됩니다. 작업이 끝나면 앱은 endBackgroundTask : 메소드를 호출하여 시스템이 작업을 완료하고 일시 중단 될 수 있음을 알립니다.

백그라운드에서 컨텐츠를 다운로드

파일을 다운로드 할 때 앱은 NSURLSession 객체를 사용하여 다운로드를 시작해야 앱이 일시 중지되거나 종료 될 경우 다운로드 프로세스를 제어 할 수 있습니다. 백그라운드 전송을 위해 NSURLSession 객체를 구성하면 시스템은 이러한 전송을 별도의 프로세스로 관리하고 정상적인 방법으로 상태를 다시 앱에보고합니다. 전송이 진행되는 동안 앱이 종료되면 시스템은 백그라운드에서 전송을 계속하고 전송이 완료되거나 하나 이상의 작업에 앱의주의가 필요할 때 앱을 시작합니다 (적절한 경우). 백그라운드 전송을 지원하려면 NSURLSession 객체를 적절하게 구성해야합니다. 세션을 구성하려면 먼저 NSURLSessionConfiguration 객체를 만들고 여러 속성을 적절한 값으로 설정해야합니다. 그런 다음 세션을 만들 때 해당 구성 객체를 NSURLSession의 적절한 초기화 메서드에 전달합니다.

오래동안 작업되는 일을 구현하기 위해 

구현하는 데 더 많은 실행 시간이 필요한 작업의 경우 일시 중단되지 않고 백그라운드에서 실행하도록 특정 권한을 요청해야합니다. iOS에서는 특정 앱 유형 만 백그라운드에서 실행할 수 있습니다.

*음악 플레이어 앱과 같이 백그라운드에서 사용자에게 가청 콘텐츠를 재생하는 앱

*백그라운드에서 오디오 콘텐츠를 기록하는 앱

*내비게이션 앱과 같이 항상 사용자에게 위치 정보를 계속 제공하는 앱

*VoIP (Voice over Internet Protocol)를 지원하는 응용 프로그램

*새 콘텐츠를 정기적으로 다운로드하고 처리해야하는 앱

*외부 액세서리를 정기적으로 업데이트하는 앱

이러한 서비스를 구현하는 앱은 지원하는 서비스를 선언하고 해당 서비스의 관련 측면을 구현하기 위해 시스템 프레임 워크를 사용해야합니다. 서비스를 선언하면 시스템에서 사용하는 서비스를 알 수 있지만 어떤 경우에는 실제로 응용 프로그램이 일시 중단되는 것을 막는 시스템 프레임 워크입니다.


작은 양의 콘텐츠를 기회로 가져 오기

주기적으로 새 콘텐츠를 확인해야하는 앱은 시스템에 깨어나서 해당 콘텐츠에 대한 가져 오기 작업을 시작할 수 있도록 요청할 수 있습니다. 이 모드를 지원하려면 Xcode 프로젝트의 Capabilities 탭에있는 Background modes 섹션에서 Background fetch 옵션을 활성화하십시오. 앱의 Info.plist 파일에 가져 오기 값이있는 UIBackgroundModes 키를 포함시켜이 지원을 활성화 할 수도 있습니다.이 모드를 사용한다고해도 시스템이 앱에 백그라운드 가져 오기를 수행 할 수있는 시간을 보장 할 수는 없습니다. 


푸시 알림을 사용하여 다운로드 시작

앱에서 새 콘텐츠를 사용할 수 있을 때 서버가 사용자의 기기에 푸시 알림을 보내는 경우 백그라운드에서 앱을 실행하도록 시스템에 요청하여 새로운 콘텐츠를 바로 다운로드 할 수 있도록 할 수 있습니다. 이 백그라운드 모드의 의도는 사용자가 푸시 알림을 볼 때와 앱이 관련 콘텐츠를 표시 할 수있을 때까지 경과하는 시간을 최소화하는 것입니다. 앱은 대개 사용자가 알림을 보는 것과 거의 같은 시간에 깨어나지 만, 그렇지 않은 경우보다 많은 시간을 제공합니다.

이 백그라운드 모드를 지원하려면 Xcode 프로젝트의 Capabilities 탭에있는 Background modes 섹션에서 Remote notification 옵션을 활성화하십시오. (앱의 Info.plist 파일에 원격 알림 값이있는 UIBackgroundModes 키를 포함 시켜서이 지원을 사용할 수도 있습니다.)

다운로드 작업을 시작하기위한 푸시 알림의 경우 알림의 페이로드에는 해당 값이 1로 설정된 콘텐츠 사용 가능한 키가 포함되어야합니다. 키가 있으면 시스템이 백그라운드에서 앱을 시작 (또는 백그라운드로 시작)하고 앱 위임자의 애플리케이션 : didReceiveRemoteNotification : fetchCompletionHandler : 메소드를 호출합니다. 해당 메소드를 구현하면 관련 콘텐츠를 다운로드하여 앱에 통합해야합니다.


백그라운드에 있는 동안 사용자의 관심을 끄는 방법 (알림)

알림은 일시 ​​중지되었거나 백그라운드에 있거나 실행 중이 아닌 앱에 대해 사용자의 관심을 끌 수 있는 방법입니다. 앱은 로컬 알림을 사용하여 알림을 표시하고, 소리를 내며, 앱의 아이콘에 배지를 부여하거나, 세 가지를 조합하여 사용할 수 있습니다. 예를 들어 알람 시계 앱은 로컬 알림을 사용하여 알람 소리를 재생하고 알람을 표시하여 알람을 비활성화 할 수 있습니다. 알림이 사용자에게 전달되면 사용자는 정보가 앱을 포 그라운드로 되돌려 놓을지를 결정해야합니다. 앱이 이미 포 그라운드에서 실행중인 경우 로컬 알림은 사용자가 아닌 앱에 조용히 전달됩니다.

로컬 알림 전달을 예약하려면 UILocalNotification 클래스의 인스턴스를 만들고 알림 매개 변수를 구성한 다음 UIApplication 클래스의 메서드를 사용하여 일정을 예약하십시오. 로컬 알림 개체에는 전달할 알림 유형 (사운드, 경고 또는 배지) 및 전달할 시간 (적용 가능한 경우)에 대한 정보가 들어 있습니다. UIApplication 클래스의 메서드는 즉시 또는 예약 된 시간에 알림을 전달하는 옵션을 제공합니다.

백그라운드로 앱이 실행되는 상황 이해하기 

백그라운드 실행을 지원하는 앱은 들어오는 이벤트를 처리하기 위해 시스템에서 다시 시작할 수 있습니다. 사용자 강제 종료 이외의 다른 이유로 앱이 종료 된 경우 다음 이벤트 중 하나가 발생하면 시스템이 앱을 실행합니다.

위치 앱용 :
-시스템은 앱의 구성된 게재 기준을 충족하는 위치 업데이트를 수신합니다.
-장치가 등록 된 영역에 들어가거나 나갔습니다. 지역은 지역 또는 iBeacon 지역 일 수 있습니다.

오디오 응용 프로그램의 경우 오디오 프레임 워크는 일부 데이터를 처리하기 위해 응용 프로그램이 필요합니다. 오디오 앱에는 오디오를 재생하거나 마이크를 사용하는 앱이 포함됩니다.

블루투스 앱의 경우 :
 - 중앙 역할을하는 앱은 연결된 주변 기기에서 데이터를 수신합니다.
 - 주변 역할로 작동하는 앱은 연결된 중앙에서 명령을받습니다.

백그라운드 다운로드 앱 :
 - 푸시 알림이 앱에 도착하고 알림의 페이로드에 값 1이있는 콘텐츠 사용 가능한 키가 포함됩니다.
 - 시스템은 새로운 콘텐츠를 다운로드하기 위해 기회가되는 순간에 앱을 깨 웁니다.
 - NSURLSession 클래스를 사용하여 백그라운드에서 콘텐츠를 다운로드하는 앱의 경우 해당 세션 개체와 관련된 모든 작업이 성공적으로 완료되거나 오류가 발생했습니다.
 - 뉴스 스탠드 앱이 시작한 다운로드가 완료됩니다.

좋은 백그라운드 앱이 되려면 

포 그라운드 앱은 시스템 리소스 및 하드웨어 사용과 관련하여 항상 백그라운드 앱보다 우선합니다. 백그라운드에서 실행중인 앱은 이러한 불일치에 대비하고 백그라운드에서 실행될 때 동작을 조정해야합니다. 특히 배경으로 이동하는 앱은 다음 가이드 라인을 따라야합니다.

* 코드에서 OpenGL ES 호출을하지 마십시오.
* 일시 중지되기 전에 Bonjour 관련 서비스를 취소하십시오.
* 네트워크 기반 소켓의 연결 오류를 처리 할 수 ​​있도록 준비하십시오. 여러 가지 이유로 앱이 일시 중지 된 상태에서 시스템이 소켓 연결을 끊을 수 있습니다.
* 백그라운드로 이동하기 전에 앱 상태를 저장하십시오. 메모리가 부족한 상태에서 배경 응용 프로그램을 메모리에서 제거하여 여유 공간을 확보 할 수 있습니다.
배경으로 이동할 때 불필요한 오브젝트에 대한 강력한 참조를 제거하십시오. .
* 일시 중단되기 전에 공유 시스템 자원 사용을 중지하십시오.
* 외부 액세서리에 대한 연결 알림 및 연결 해제 알림에 응답합니다.
* 백그라운드로 이동할 때 활성 경고에 대한 리소스를 정리합니다.
* 백그라운드로 이동하기 전에보기에서 중요한 정보를 제거하십시오.
* 백그라운드에서 실행하는 동안 최소한의 작업을 수행하십시오.

예제 ) Background Modes Tutorial: Getting Started 


Comments