Tag Archives: Watch

애플와치 앱 UI 개발

당신의 앱 구현의 시작점은 스토리보드 씬을 정의하는 것입니다. 각 씬은 앱의 유저 인터페이스 부분을 담당합니다. 당신은 다른 애플 와치 사이즈에 맞추어 씬을 커스터마이징 하고 다른 관점의 인터페이스를 설정할 수 있습니다.

watchkit_ui_essential_01

스토리보드 씬들을 조립

WatchKit 앱은 iOS 앱들과 같은 레이아웃 모델을 사용할 수 없습니다. WatchKit 앱 인터페이스의 씬이 조립될 때는 빈공간에 원하는데로 임의의 배치를 하는방식으로 뷰 계층을 생성할 수 없습니다. 대신에 XCode가 라인단위로 세로로 쌓는 형태로 아이템을 적절히 정렬해주며 사용자는 엘리먼트를 당신의 씬에 추가할 수 있습니다. 앱이 실행되는 시점에 애플와치는 이러한 엘리먼트들을 사용가능한 공간에 적절히 배치를 하게됩니다.

비록 XCode가 당신의 인터페이스의 전반적인 레이아웃을 조작하긴 하지만 WatchKit은 씬의 아이템들이 적당한 위치에 놓이도록 방법을 제공합니다. 대부분의 아이템의 크기나 위치는 속성 인스펙터를 이용해 설정할 수 있습니다. 아이템의 위치를 변경하는것은 엘리먼트 스택의 현재 위치에서의 가로, 세로 정렬을 결정하게 합니다. 크기 설정은 아이템의 고정된 가로 길이는 정의하거나 사용가능한 공간에 맞추어 리사이즈 되도록 설정할 수 있습니다.

그룹 객체는 당신의 인터페이스의 다른 엘리먼트들을 정렬하기 위한 또다른 중요한 기능을 제공합니다. 그룹 엘리먼트들은 그룹내에서 가로 또는 세로로 엘리먼트들을 정렬할 수 있는 설정을 제공하는 다른 엘리먼트들을 위한 컨테이너 역할을 합니다. 다른 그룹들간에 중첩된 그룹을 구성할 수 있으며 그룹간에 간격이나 삽입된 아이템들의 크기나 위치를 설정할 수 있습니다. 그룹은 기본적으로 보여지는 부분이 없지만 원한다면 배경 색상이나 이미지를 넣을 수 있습니다.

watchkit_ui_essential_02

위의 그림은 당신의 스토리보드 파일에서 다른 엘리먼트들을 어떻게 배치하는지를 보여주는 그림입니다. 첫 3개의 엘리먼트들은 인터페이스 컨트롤러 영역안에서 다른 정렬값을 가진 라벨입니다. 라벨들의 바로 밑에는가로로 배치된 두개의 그림을 가지고 있는 그룹 객체입니다. 그룹 밑으로는 구분선과 버튼이 세로로 쌓여있게 됩니다.

XCode에서 인터페이스를 생성하게 되면 각 객체들은 가능한한 사용가능한 공간에 맞추어 리사이즈됩니다. 앱 인터페이스는 애플와치의 두가지 사이즈에 동일하게 실행될 수 있어야 합니다. 시스템에 화면 크기에 맞추어 객체들의 리사이즈를 맡기는것은 각각의 디바이스에 대응하기 위한 별도의 코드를 작성하는 수고를 덜어 줄 수 있습니다.

다른 디스플레이 크기를 수용

XCode는 애플와치의 다른 사이즈들의 인터페이스를 커스터마이징 할 수 있는 기능을 제공합니다. 기본적으로 모든 사이즈의 애플와치에 공통적으로 적용될 수 있는 형태로 사이즈를 설정하도록 되어있지만 다른 디바이스에 특별히 다른 사이즈가 필요로 한다면 거기에 맞추어 커스터마이징 할 수 있습니다. 예를 들어 아이템들의 레이아웃이나 여백의 미세조정이나 크기에 따라 다른 이미지를 선택하도록 할 수 있습니다.

아이템이 디바이스별로 다른 사이즈를 지원하도록 커스터마이징 하기 위해서는 속성 인스펙터에서 + 버튼을 눌러 디바이스에 기본적으로 주어진 값을 변경할 수 있습니다. + 버튼을 눌러 새로운 디바이스에 특화된 속성을 설정할 수 있습니다. 여기에 설정한 값은 선택한 디바이스에만 적용되는 값입니다.

watchkit_ui_essential_03

위의 그림은 애플와치 42mm 크기의 스크린에 맞추어 어떻게 텍스트 크기를 조정하는지를 나타낸 그림입니다.

사용자들로 하여금 다른 크기의 애플와치들 사이에 앱 인터페이스의 차이점이 확연히 느껴지지 않도록 해야 합니다. 그렇기 때문에 디바이스 크기별로 커스터마이징 하는것을 최소화해야 합니다. 가능한한 간격과 여백은 인터페이스가 레이아웃을 기반하여 작동하도록 제한하십시오. 다른 레이아웃들간에 모든 인터페이스 객체들을 제거할 수 있지만 이 방법은 추천하지 않습니다. 모든 크기의 애플와치에서 동일한 인터페이스 오브젝트가 보여지도록 해주시기 바랍니다.

디바이스 크기별로 다른 커스터마이징이 정상적으로 적용되었는지를 확인하기 위해서는 스토리보드 에디터 하단에 있는 컨트롤을 이용하여 디바이스 크기를 변경할 수 있습니다. 스토리보드 에디터는 기본적으로 “Any Screen Size” 모드를 제공하며 모든 크기의 애플와치의 스크린 크기를 선택할 수 있습니다. 특정한 스크린 크기 모드로 설정을 변경하면 거기서 변경된 설정은 현재 선택된 디바이스 크기에서만 적용됩니다.

실행 시점에 인터페이스 변경하기

실행 시점에 인터페이스 컨트롤러는 스토리보드 씬의 객체들에 대해 다음과 같은 변경을 할 수 있습니다.

  • 데이터 값을 설정하거나 변경
  • 수정가능한 객체의 외관을 변경
  • 객체의 크기를 변경
  • 객체의 투명도를 변경
  • 객체를 감추거나 보여지도록 변경

당신은 인터페이스에 새로운 객체를 추가하거나 이미 위치한 객체들의 순서를 변경할 수 없습니다. 마찬가지로 객체를 제거하는것도 불가능하지만 일시적으로 레이아웃에서 감추는 방식으로 제거하는 효과를 얻을 수 있습니다. 아이템이 감춰지면 다른 객체가 이 아이템이 차지했던 공간을 채우게 됩니다. 빈 공간을 채우지 않도록 하기위해서는 제거하려는 아이템의 알파(Alpha)값을 0으로 변경하면 됩니다. 씬에서 객체를 감추는 방법에 대해 더 알아보려면 Hiding Interface Objects 를 보시기 바랍니다.

watchkit_ui_essential_04

앱의 주요 색상 설정

모든 WatchKit 앱은 다음의 UI 엘리먼트들에 적용되는 주요 색상을 가집니다.

  • 상태바의 타이틀 문자열
  • 짧게 보여지는 노티피케이션의 앱 이름

앱의 주요 색상은 스토리보드의 Global Tint 속성에 저장됩니다. 이 속성에 접근하기 위해서는 당신의 스토리보드는 선택하고 파일 인스펙터(File Inspector)에 들어갑니다. 여기서 이미 지정되어있는 색상을 선택하여 팝업 메뉴로부터 원하는 색상을 선택할 수 있습니다.

인터페이스의 국제화

WatchKit 앱의 스토리보드는 기본적으로 국제화를 지원하도록 되어있습니다. 이 기능은 당신의 프로젝트에 Localizable.strings 파일을 추가함으로써 자동으로 지원하게 됩니다. 간단하게 이 파일안에서 각 언어별 타겟별로 번역된 문자열을 입력하고 당신의 앱에 추가해주시면 됩니다. 앱이 실행되는 시점에 스토리보드 씬이 생성되면 XCode는 적절한 언어를 선택하여 보여주게 됩니다.

당신의 라벨이나 컨트롤들이 가지고 있는 텍스트가 충분한 공간을 가질 수 있도록 확장하여 배치해 주십시오. 여러 버튼을 하나의 라인에 배치하기 보다는 버튼의 타이틀이 충분히 보여질 수 있도록 가로로 배치하시기 바랍니다.

텍스트나 이미지를 프로그램적으로 설정하기 위해서는 iOS 또는 OS X와 같은 방식으로 다국어 지원을 해주시면 됩니다.

  • NSLocalizedString 매크로를 사용하여 리소스 파일로부터 문자열을 로드합니다.
  • 양식이 적용된 숫자값을 위해 NSNumberFormatter 객체를 사용합니다.
  • 날짜와 시간에 양식을 적용하기 위해 NSDateFormatter 객체를 사용합니다.

WatchKit 익스텐션을 사용할 때 NSLocale 객체는 사용자의 애플 와치에 설정된 언어 설정을 반환합니다. 이 클래스를 사용하여 사용자가 선호하는 언어와 다른 언어 정보를 가져올 수 있습니다. 당신의 앱을 국제화 하는것에 관심이 있다면 Internationalization and Localization Guide 를 확인하시기 바랍니다.

참고 : WatchKit Apps – UI Essentials

애플와치 WatchKit 앱 아키텍쳐

애플와치에서 구동되는 앱은 WatchKit 앱, WatchKit 익스텐션 두개의 파트로 나뉘어집니다. WatchKit 앱은 사용자의 애플 와치에 올라가며 스토리보드와 리소스 파일이 포함되지만 실행 코드는 포함되지 않습니다. WatchKit 익스텐션의 경우 사용자의 아이폰에 존재하게 되며 당신의 iOS 앱의 내부에 포함됩니다. WatchKit 익스텐션은 WatchKit 앱의 인터페이스를 관리하기 위한 코드와 리소스 파일을 가지게 됩니다.

Apple-Watch-Logo

WatchKit 앱과 WatchKit 익스텐션은 서로 협력하여 앱의 인터페이스를 구현합니다. 사용자가 애플와치의 당신의 앱에 어떤 행위를 취하면 WatchKit 앱은 인터렉션을 수행하기 위해 당신의 적절한 스토리보드를 선택하게 됩니다. 예를 들어 만약 사용자가 당신의 앱의 Glance를 본다면 당신의 Glance 씬이 선택될 것입니다. 씬이 선택된 다음에는 WatchKit 은 연결되어있는 아이폰으로 하여금 WatchKit 익스텐션을 실행하고 해당 씬을 관리하기 위해 필요한 오브젝트들을 생성할 것입니다. 씬이 완전히 생성이 된 후에 그 화면은 애플 와치에 보여질것입니다. WatchKit 앱과 WatchKit 익스텐션간의 정보의 통신은 씬의 뒤에서 보이지 않게 일어나게 됩니다.

watchkit_app_architecture_01

각 씬은 하나의 WKInterfaceController 의 인스턴스인 인터페이스 컨트롤러(Interface Controller) 객체들에 의해 관리됩니다. WatchKit 의 인터페이스 컨트롤러는 iOS의 뷰 컨트롤러(View Controller)와 같은 목적을 제공합니다. 이 인터페이스 컨트롤러는 컨텐츠를 관리하거나 스크린에 보여주고 사용자의 인터렉션을 수행합니다. 하지만 뷰 컨트롤러와는 다르게 인터페이스 컨트롤러는 당신의 인터페이스의 실제 뷰를 직접 조작하지는 않습니다. 실제 뷰들은 WatchKit에 의해 씬의 뒤에서 관리되게 됩니다.

WatchKit 앱은 일반적으로 각각 다른 형태의 모습을 가진 다수의 인터페이스 컨트롤러를 가질 수 있습니다. 한 화면에 한번에 하나의 인터페이스 컨트롤러만이 보여질 수 있기 때문에 앱은 유저의 특정 액션에 대해 새로운 인터페이스 컨트롤러를 보여주게 됩니다. (화면이 작고 한번에 하나의 인터페이스 컨트롤러만을 보여줄 수 있으니 유저액션에 대한 처리를 할때 새로운 인터페이스 컨트롤러를 보여주는식으로 화면 전환을 하라는 말인듯 하네요) 앱은 인터페이스 컨트롤러를 모달창 형태로 보여줄 수 있습니다. 인터페이스 컨트롤러가 보여질 때 어떤 형태의 네비게이션 스타일을 가질지도 결정할 수 있습니다. 더 많은 정보는 Interface Navigation을 참고하세요.

WatchKit 앱 라이프 사이클

애플와치와의 사용자 인터렉션은 당신의 앱을 실행하고 앱의 라이프사이클을 발생시킵니다. 사용자는 홈스크린에서 앱을 직접 실행하거나 Glance 또는 당신의 커스텀 UI를 가진 노티피케이션을 통해 앱을 실행할 수 있습니다. 각각의 이러한 인터렉션은 당신의 WatchKit 앱과 그에 대응하는 WatchKit 익스텐션을 실행합니다. 사용자가 당신의 앱과의 인터렉션을 중단할때까지 WatchKit 앱과 WatchKit은 앞뒤로 정보를 전달합니다. 이 시점에 iOS는 다음 사용자 인터렉션까지 익스텐션을 일시 중단시킵니다.

실행 시점에 WatchKit은 자동으로 현재 인터렉션에 적절한 씬을 로드합니다. 만약 사용자가 당신 앱의 Glance를 보았다면 스토리보드로부터 Glance 씬이 로드되게 됩니다. 만약 사용자가 당신의 앱을 직접 실행하였다면 당신앱의 시작 씬을 로드할 것입니다. 씬이 로드된 다음에는 WatchKit 익스텐션에게 씬을 보여주기 위한 준비와 함께 이 씬에 상응하는 인터페이스 컨트롤러를 생성하도록 요청합니다.

watchkit_app_architecture_02

인터페이스 컨트롤러의 Init과 awakeWithContext: 메소드를 이용하여 인터페이스 객체를 세팅하거나 인터페이스가 적절히 보여질 수 있도록 필요한 데이터를 로드하는 작업을 수행합니다. willActivate 에서 당신의 인터페이스 컨트롤러를 초기화하는 작업을 수행하지 마십시오. willActivate 메소드는 당신의 인터페이스가 화면에 보여지기 전에 짧은시간동안 호출되는 메소드이기 때문에 이 메소드는 마지막 순간에 변경을 해야 하는 무언가를 위해서만 사용해야 합니다. 예를 들어 애니메이션을 시작하거나 당신의 인터페이스가 화면에 보여지는 시점에 수행되어야만 하는 다른 작업들을 수행할 수 있습니다.

인터페이스 컨트롤러가 화면에 보여지는 동안 사용자의 인터렉션들은 인터페이스 컨트롤러에 구현된 커스텀 메소드들에 의해 처리됩니다. 사용자의 테이블, 버튼, 스위치, 슬라이더 및 다른 컨트롤들에 대한 액션들에 대해 응답할 수 있도록 WatchKit은 당신의 액션 메소드들을 호출합니다. 당신은 이러한 액션 메소드들을 사용하여 인터페이스의 내용을 업데이트하거나 다른 연관된 작업을 수행할 수 있습니다. 다른 시점에 수행되어야 하는 작업의 경우 NSTimer 객체를 사용하여 당신이 지정한 시점에 코드를 실행할 수 있습니다. (Glance는 엑션 메소드를 지원하지 않습니다. 당신 앱의 Glance를 탭하게 되면 항상 앱이 구동됩니다)

당신의 WatchKit 익스텐션은 사용자가 애플와치에서 구동중인 당신의 앱과 인터렉션을 하는 동안만 실행됩니다. 애플와치와의 인터렉션은 매우 간단한 작업을 의미합니다. 그렇기 때문에 인터페이스 컨트롤러는 가볍고 절대 긴 시간이 소요되지 않는 작업만을 수행해야 합니다. 사용자가 명시적으로 앱을 종료하거나 애플와치와의 인터렉션을 중단하면 iOS는 현재 인터페이스 컨트롤러를 비활성화 시키고 익스텐션을 일시 중지시킵니다.watchkit_app_architecture_03

앱 라이프별 다른 단계의 작업 수행

앱의 생명주기상 각 단계별로 필요한 처리를 할 수 있도록 iOS가 당신의 WKInterfaceController 객체의 메소드들을 호출합니다. 다음은 당신의 인터페이스 컨트롤러들에서 거의 대부분 구현되어야 하는 중요한 메소드들 목록입니다.

  • init 이 메소드는 당신의 인터페이스 컨트롤러가 최초로 초기화 될때 호출됩니다.
  • awakeWithContext: 이 메소드는 사용 가능한 컨텍스트 데이터를 이용하여 인터페이스 컨트롤러를 설정하도록 해줍니다. 이 메소드 내에서 데이터를 로드하거나 스토리보드상의 라벨, 이미지, 테이블 또는 다른 인터페이스 오브젝드들을 업데이트할 수 있습니다. 컨텍스트 데이터는 새로운 인터페이스 컨트롤러를 설정하는데 도움을 주는 역할을 합니다. 예를 들어 계층형 인터페이스에서 새로운 인터페이스가 푸시될 때 다음 레벨에서 보여져야 하는 데이터를 가진 컨텍스트를 특정할 수 있습니다. 컨텍스트 객체를 제공하는것을 추천하지만 필수사항은 아닙니다.
  • willActivate 이 메소드는 사용자에게 인터페이스가 곧 보여지려는 시점에 호출됩니다. 이 메소드는 당신의 인터페이스에서 작은 변화를 줄 경우에만 사용해야 합니다. 예를 들어 새로운 데이터에 담겨 있는 정보를 이용하여 라벨을 업데이트하는 경우가 있을 수 있겠습니다. 큰 규모의 인터페이스 초기화는 init 또는 awakeWithContext: 메소드에서 수행하시기 바랍니다.
  • didDeactivate 이 메소드를 이용하여 당신의 인터페이스를 지우거나 중단 상태로 변경할 수 있습니다. 예를 들어 이 메소드에서 타이머나 에니메이션을 중단시킬 수 있습니다. 이 메소드에서는 어떤 인터페이스 객체에도 값을 세팅해서는 안됩니다. 다시 앱이 활성화 될때 willActivate가 다시 호출될것이며 모든 인터페이스 객체의 세팅 작업은 무시됩니다.

당신의 활성화 코드를 iOS 시뮬레이터에서 디버깅 하기

테스트를 하는동안 시뮬레이터를 잠금 또는 잠금 해제를 하면서 당신의 활성화/비활성화 코드가 예상하는데로 정상 동작하는지 여부를 테스트할 수 있습니다. Hardware > Lock 명령을 통해 시뮬레이터를 잠그게 되면 WatchKit은 현재 인터페이스 컨트롤러의 didDeactivate 메소드를 호출합니다. 이후에 시뮬레이터를 잠금 해제 하게 되면 WatchKit은 인터페이스 컨트롤러의 willActivate를 호출합니다.

iOS 앱이 가지고 있는 데이터를 공유하기

만약 당신의 iOS 앱과 WatchKit 익스텐션이 같은 데이터를 토대로 동작한다면 공유 앱 그룹을 사용하여 데이터를 저장할 수 있습니다. 앱 그룹은 여러 프로세스들이 접근할 수 있는 보안 컨테이너입니다. WatchKit 익스텐션과 iOS 앱은 별개의 샌드박스 환경에서 실행되기 때문에 일반적인 방법으로는 파일을 공유하거나 직접 통신을 하는것이 불가능합니다. 앱 그룹은 이들처럼 서로 다른 두개의 프로세스가 파일 또는 정보를 공유할 수 있게 해줍니다.

당신의 iOS 앱과 WatchKit 익스텐션의 Capabilities 탭에서 공유 앱그룹 설정을 할 수 있습니다. 앱 그룹이 활성화 되면 필요에 따라 자격 파일(Entitlements File)을 각 타겟에 추가하고 com.apple.security.application-groups 자격도 그 파일에 추가합니다. 데이터를 공유하기 위해서 각 타겟들은 반드시 같은 앱그룹이 선택되어야 합니다.

watchkit_app_architecture_04

실행 시점에서 서로다른 프로세스간 공유 컨테이너의 디렉토리안의 파일들을 읽고 쓰는 방식으로 공유할 수 있습니다. 컨테이너 디렉토리에 접근하기 위해서는NSFileManager 의 containerURLForSecurityApplicationGroupIdentifier: 메소드를 이용하여 디렉토리의 기본 URL을 가져올 수 있습니다. 제공된 URL의 디렉토리를 순환하거나 디렉토리안의 파일에 대한 새로운 URL을 생성할 수 있습니다.

환경 설정을 앱간에 공유하기 위해서는 공유 그룹의 식별자를 사용하여 NSUserDefaults 객체를 생성하시면 됩니다. NSUserDefaults 의 initWithSuiteName: 메소드는 사용자의 기본데이터를 공유하여 접근하는것을 허용케합니다. 각 프로세스들은 이 데이터에 접근할 수 있고 값을 변경할 수 있습니다.

iOS 앱과 직접 통신하기

iOS 앱과 매우 밀접하게 동작하는 애플와치 앱은 openParentApplication:reply: 메소드를 이용하여 요청을 보내고 그 응답을 받을 수 있습니다. WatchKit 익스텐션은 백그라운드 실행 모드를 지원하지 않습니다. 이 익스텐션은 애플와치에서 사용자가 앱에 어떤 인터렉션을 수행중일때만 동작합니다. 경우에 따라 앱은 좀 더 제한이 적은 환경을 가지고 백그라운드 작업을 수행하거나 WatchKit 익스텐션을 통해 정보를 수집할 수 있습니다. 사용자의 위치를 가져오거나 하는 좀 더 많은 시간이 소요되는 활동들은 iOS 앱에 의해 수행되고 그 결과를 WatchKit 익스텐션으로 전달할 수 있습니다.

openParentApplication:reply: 메소드를 호출하게 되면 iOS는 백그라운드 상태의 iOS앱을 실행하거나 깨우게 되며 application:handleWatchKitExtensionRequest:reply: 앱 델리게이트를 호출합니다. 이 앱 델리게이트를 이용해 요청했던 작업의 결과를 WatchKit 익스텐션으로 돌려줄 수 있습니다.

참고 : WatchKit App Architecture