Programming/Mac & iOS

[iOS] App Extension : Today view (Widget)

MB Kyle KWON 2014. 9. 18. 09:13


    iOS8에서 새롭게 제공하는 기능 중에 하나이다. 기존 안드로이드에서 이미 제한 기능이다. iOS8에서 새롭게 추가되면서 더욱 편리한 기능을 제공할 것으로 생각된다. 현재(2014.09.18) iOS8이 정식 릴리즈된 시점에서 필자가 사용하는 앱 중에 에버노트와 드롭박스는 발 빠르게 이 기능을 대처하고 있다. 이제 iOS8 위젯 기능을 사용하기 위한 과정을 알아보자.


    먼저, 나의 앱 프로젝트에 App Extension(이하 'AE')을 추가한다. AE는 호스트 앱이 구현하고 호스트 앱에 AE를 추가 구현하는 형태로 개발한다. AE는 다른 앱들에서 사용할 수 있다. 호스트 앱에는 AE에서 사용하는 설정이나 정보를 처리하는 기능들을 얻도록 한다. 현재 Xcode 6에서는 아래와 같이 iOS에서 사용 가능한 6가지 AE들을 제공하고 있다.



    기존의 프로젝트에 새로운 타겟을 추가한다. AE 탭을 누르면 새롭게 추가할 수 있는 AE 목록이 보인다. 여기서는 Today Extension을 선택한다. 새로운 타겟을 생성하면서 Today Extension을 위한 템플릿이 생성된다. 'NCWidgetProviding'이 구현된 템플릿이 있다. 'NCWidgetProviding'은 optional method를 2가지 재공한다. 먼저 'widgetPerformUpdateWithCompletionHandler(completionHandler:)'이라는 method이다. 이는 위젯이 표시되는 순간, 사용되는 정보의 수정을 체크하여 갱신되도록 요청하는데 쓰인다. 물론 여기서 정보가 수정되었는지를 체크하는 부분은 개발자가 이 method에 직접 구현해 넣으면 된다. 구현을 하고난 후, 'comletionHandler(NCUpdateResult)'를 호출하면 된다. 'NCUpdateResult'는 3가지의 case를 제공하는 enum이다. '.NewData / .NoData / .Failed'의 3가지를 제공한다. 앞에서부터 하나씩 설명하면 '.NewData'는 새로운 정보의 수정이 발생하여 위젯을 갱신하고자 할 때 사용된다. '.NoData'는 갱신이 불필요할 경우이 사용되고 'Failed'는 정보의 수정을 확인하는 과정에서 실패할 경우 호출된다. 이외에 'NCWidgetProviding'에서 제공하는 'widgetMarginInsetsForProposedMarginInsets() '를 통하여 위젯의 여백을 조정할 수 있다.


    AE에서 표시할 정보를 가져오기 위해서 호스트앱과 Extension간의 데이터를 공유하는 저장소가 필요하다. 저장소는 NSUserDefault를 사용한다. NSUserDefault로 앱간의 데이터 공유를 위해서 각 타겟에 동일한 AppGroup을 추가한다. AppGroup은 각 타겟의 'Capabilities'에서 추가 가능하다. 추가된 AppGroup을 'NSUserDefaults(suiteName:) '의 suiteName으로 사용함으로써 동일한 NSUserDefault를 공유할 수 있다. 아래의 예제를 참고하는 것이 설명만 보는 것보다 이해가 빠를 것이라고 생각한다.


P. S. Today view는 네트워크 및 UI 입출력을 허용하는 반면, 파일 입출력을 지원하지 않는다. 그리고 과도한 네트워크 사용은 피하는 것이 좋다. 다른 process보다 Today view의 우선순위가 낮아 반응성을 저해할 수 있기 때문이다.


AppExtensionEx.zip