본문 바로가기
WWDC

[WWDC16] Extending Your Apps with SiriKit

by 고고 2022. 5. 2.

유튜브 링크: https://www.youtube.com/watch?v=7TZHLjdViYA

 

목차

1. SiriKit 도입 준비하기

2. Intents extension 추가하기

3. Siri에서 UI 제공하기

 

1. SiriKit 도입 준비하기

 

Embedded frameworks(포함된 프레임워크)에는 네트워킹, 데이터 모델, 결정 로직, UI가 있습니다. Intents extension과 App의 코드를 공유하여 재사용성을 높일 수 있습니다.

 

 

Unit tests에서는 Mock intents로 앱이 의도대로 응답하는지 확인해야 합니다.

 

데모앱에는 3가지의 Intent를 가지고 있습니다. 이것을 하나의 Intent extension으로 관리하면 코드가 너무나 방대해집니다. 하지만 한 Intent 당 하나의 Intent extension으로 관리하면 반복되는 코드(보일러 플레이트 코드)가 많아집니다.

 

 

데모 앱에서는 코드의 재사용성을 최대한 늘리기 위해 Audio와 VideoCallIntent를 하나의 Intent extension으로 관리합니다.

 

 

2. Intents extension 추가하기

세 가지 단계를 통해 시작할 수 있습니다.

 

- extension target 추가하기

 

 

- Info.plist 설정하기

IntentsSupported에 Intents 배열을 넣으면 됩니다. IntentsRestrictedWhileLocked는 화면이 잠겨있을 때에는 사용하지 못하게 할 Intents 배열을 넣으면 되고, 옵셔널입니다.

 

 

- Principal class 수정하기

 

 

Info.plist를 수정하는 예시입니다.

 

 

Siri extension target을 추가하였을 때 자동으로 생성되는 principal class입니다.

 

Handler를 따로 생성하여 반환하도록 수정하였습니다.

 

 

이제 앱 로직에 대해 알아보겠습니다.

앱 로직의 단계는 Resolve, Confirm, Handle이 있습니다. 

우선 Resolve는 파라미터를 검증하고 시리가 유저에게 질문하는 것을 도울 필요가 있다면 구현합니다.

 

 

데모앱에서는 수신자를 찾기 위해 연락처를 검색합니다. 이때 딱 한 결과 혹은 여러 결과, 아니면 결과가 나오지 않을 수 있습니다.

 

 

또한 데모앱에서는 content가 필요합니다. 따라서 recipients(수신자), content(내용)을 위해 resolve 메소드를 작성해야 합니다. 파라미터를 검증하는 과정입니다.

 

 

Confirm 단계에서는 액션을 취하기 전에 유저에게 확인받는 단계입니다. 예를 들어 송금 전에 한번 더 확인할 수 있겠죠. 또한 앱으로 이동하여 유저 인증을 다시 받을 수 있습니다.

 

 

Handle에서는 완료되었는지 말해줍니다.

 

 

예제입니다. 저번에 작성한 IntentHandler에 resolve, confirm, handle 함수를 넣습니다.

 

resolveRecipients함수에서는 recipients의 갯수에 따라 completion에 넣는 결과가 달라집니다.

2개 이상인 경우 모호하지 않으니 하나를 고르도록 결과에 disambiguation을 추가하고 1개인 경우 성공을 추가하고 0개인 경우 unsupported를 추가합니다.

 

 

completion에 결과를 담아 비동기로 처리합니다. 혹시 intent.recipients가 nil이라면 needsValue를 completion에 담습니다.

 

resolveContent 함수는 다음과 같습니다.

 

 

confirm함수는 다음과 같습니다.

 

 

Handle함수는 다음과 같습니다.

 

 

이제 IntentResponse의 생성자에서 보였던 userAcitvity의 타입인 NSUserActivity에 대해 알아보겠습니다.

이것은 기본적으로 시리가 하나를 생성하고 커스텀 데이터를 전달하기 위해 제공할 수 있습니다. 앱이 실행되면 받아볼 수 있습니다.

 

 

데모앱에서 사용해보겠습니다. 데모앱의 confirm 메소드에서는 유저가 인증되어 있으면 성공을, 인증되어 있지 않다면 앱실행을 요구하는 실패를 반환합니다. 이때 NSUserActivity를 만들어 userInfo를 설정하여 IntentResponse를 전달할 수 있습니다.

 

 

결과입니다.

필요한 파라미터들(대상, 내용)이 있는지 확인하는 resolve단계를 거치고

사용자에게 이렇게 보낼 것이 맞는지 confirm의 단계를 진행하고 있습니다.

 

 

마지막으로 사용자의 액션을 수행하는 Handle단계를 거치고 결과를 보여줍니다.

 

 

위의 예제가 가능했던 이유는 User-specific vocabulary 덕분입니다. 왜냐하면 시리가 특별한 이유 없이 제 연락처에 있는 이름들을 알진 않습니다. 다 앱에서 설정해준 덕분입니다.

이 User-Specific Vocabulary는 말그대로 유저에게만 사용되는 구문들입니다. 예를 들어 연락처 이름, 유저가 설정한 리스트 이름 등이 있겠습니다. 이것은 extension이 아닌 메인 앱에서의 INVocabulary API 호출을 통해 가능합니다.

 

 

데모앱에서 User-Specific Vocabulary를 업데이트하는 과정은 다음 코드와 같습니다.

이 과정은 꽤 비용이 들기 때문에 메인 큐가 아닌 다른 큐에서 작업하도록 합시다.

INVocabulary의 싱글톤 클래스에서 setVocabularyStrings를 이용해 설정합니다. 이 User specific vocabulary는 OrderedSet임을 참고해야 합니다.

 

 

3. Siri에서 UI 제공하기

UI Extension은 앱의 임팩트를 증가시킵니다. 한마디로 특이해집니다.

 

 

우선 Intents UI Extension 타겟을 추가해줍니다.

 

 

그리고 Info.plist에서 IntentsSupported를 설정합니다.

 

 

Siri는 configure 메소드로 INInteraction을 전달하며 UI extension을 호출합니다. 

UI extension은 INUIHostedViewControlling을 따르는 UIViewController를 principal class로 가지고 있습니다. 

 

 

INIteraction은 세가지 프로퍼티를 가지고 있습니다. Intent, IntentResponse, IntenthandlingStatus입니다.

 

 

UI extension의 ViewController는 pricipal class입니다.

view context를 제공하는데 view context는 enum 타입이고 iOS 10에서는 아래 사진의 두 종류(snippets, map)를 지원합니다.

 

 

 

 

Intents UI extension을 처음 만들면 ViewController, Storyboard, Info.plist가 있습니다.

 

Info.plist의 IntentsSupported를 설정해줍니다.

 

 

이런식으로 interaction의 상태에 따라 UI를 설정하여 줍니다. 유튜브 영상에서는 2분 정도가 잘려 이렇게 끝났습니다.

 

 

데모를 통해 SiriKit의 Intents extension과 Intents UI extension을 작성하는 방법을 알 수 있었습니다.

댓글