본문 바로가기

iOS 앱 개발자 프로젝트

[iOS] Widget - IntentConfiguration (3)

앞의 위젯 (1), (2)의 내용에서는 Widget Extension의 Configuration을 이해하기 위해

화면 노출과 관련한 Provider와 View 파트를 중심으로 살펴보았다.

 

오늘은 intent definision에서 우리가 category와 parameter를 설정했을 때,

xCode가 자동으로 완성하는 custom class에 대해 알아보자.

 

 


 

 

아래와 같이 이름을 정하고 옵션을 설정한 후 빌드하면 TodoList가 만들어진다.

 

 

 

 

 


다음은 여기까지의 과정을 통해 Xcode Custom Intent 대한 Custom Class 자동으로 생성해준다.

 

이 Class 코드는 큰 틀에서 보면, 아래와 같이 양분화 할 수 있고,

 

1) TodoListIntent의 사용자 정의 Intent와

2) 이를 처리하기 위한 프로토콜 및 응답 클래스 정의

 

좀 더 세부적으로 보면 아래와 같다. 

 

1) TodoListIntent 클래스

2) TodoListIntentHandling 프로토콜

3) TodoListIntentResponseCode 열거형

4) TodoListIntentResponse 클래스

 

 

찬찬히 살펴보자.

 

1) TodoListIntent 클래스

  • TodoListIntent 클래스는 INIntent 클래스를 상속받아 인텐트를 정의
  • @NSManaged public var parameter: String?는 인텐트의 파라미터 → parameter라는 이름의 문자열 타입의 파라미터가 정의되어 있다.
@available(iOS 12.0, macOS 11.0, watchOS 5.0, *)
@available(tvOS, unavailable)
@objc(TodoListIntent)
public class TodoListIntent: INIntent {

    @NSManaged public var parameter: String?

}

 

 

2) TodoListIntentHandling 프로토콜

  • TodoListIntentHandling 프로토콜은 NSObjectProtocol을 상속 받는다.
  • confirm과 handle 메서드 정의 → 선택적으로 구현할 수 있다.
    • confirm(intent:completion:) 및 confirm(intent:) async 메서드는 인텐트를 처리하기 전에 유효성을 확인
    • handle(intent:completion:) 및 handle(intent:) async 메서드는 인텐트를 실제로 처리
@available(iOS 12.0, macOS 11.0, watchOS 5.0, *)
@available(tvOS, unavailable)
@objc(TodoListIntentHandling)
public protocol TodoListIntentHandling: NSObjectProtocol {

    @available(*, renamed: "confirm(intent:)")
    @objc(confirmTodoList:completion:)
    optional func confirm(intent: TodoListIntent, completion: @escaping (TodoListIntentResponse) -> Swift.Void)

    @available(iOS 13.0, macOS 11.0, watchOS 6.0, *)
    @objc(confirmTodoList:completion:)
    optional func confirm(intent: TodoListIntent) async -> TodoListIntentResponse

    @available(*, renamed: "handle(intent:)")
    @objc(handleTodoList:completion:)
    optional func handle(intent: TodoListIntent, completion: @escaping (TodoListIntentResponse) -> Swift.Void)
    
    @available(iOS 13.0, macOS 11.0, watchOS 6.0, *)
    @objc(handleTodoList:completion:)
    optional func handle(intent: TodoListIntent) async -> TodoListIntentResponse

}

 

 

3) TodoListIntentResponseCode 열거형

  • TodoListIntentResponseCode 열거형은 인텐트 응답의 상태를 나타내는 데 사용된다.
  • 각 케이스는 응답의 상태를 나타낸다.
    • unspecified: 지정되지 않음
    • ready: 준비 완료
    • continueInApp: 앱에서 계속
    • inProgress: 진행 중
    • success: 성공
    • failure: 실패
    • failureRequiringAppLaunch: 앱 실행이 필요한 실패
@available(iOS 12.0, macOS 11.0, watchOS 5.0, *)
@available(tvOS, unavailable)
@objc public enum TodoListIntentResponseCode: Int {
    case unspecified = 0
    case ready
    case continueInApp
    case inProgress
    case success
    case failure
    case failureRequiringAppLaunch
}

 

 

4) TodoListIntentResponse 클래스

  • TodoListIntentResponse 클래스는 INIntentResponse 클래스를 상속받아 인텐트 응답을 정의.
  • code 속성은 응답의 상태를 나타내는 TodoListIntentResponseCode 값을 저장.
  • 초기화 메서드 init(code:userActivity:)는 응답 코드를 설정하고, 필요에 따라 NSUserActivity 객체를 포함할 수 있다.
@available(iOS 12.0, macOS 11.0, watchOS 5.0, *)
@available(tvOS, unavailable)
@objc(TodoListIntentResponse)
public class TodoListIntentResponse: INIntentResponse {

    @objc public fileprivate(set) var code: TodoListIntentResponseCode = .unspecified

    @objc(initWithCode:userActivity:)
    public convenience init(code: TodoListIntentResponseCode, userActivity: NSUserActivity?) {
        self.init()
        self.code = code
        self.userActivity = userActivity
    }
}

 

 

TodoListIntent 클래스에 TodoList 파라미터를 추가하고, 이를 처리하는 코드를 추가해서 이 파라미터로 여러 할 일 항목을 포함하는 목록을 나타내도록 해보자. 이를 위해 TodoItem이라는 구조체를 정의하고, TodoList 파라미터에 배열 형태로 포함시켜야 한다.

 

 

 

Xcode가 자동 완성한 전체코드 ▽

 

//
// TodoListIntent.swift
//
// This file was automatically generated and should not be edited.
//

#if canImport(Intents)

import Intents

@available(iOS 12.0, macOS 11.0, watchOS 5.0, *) @available(tvOS, unavailable)
@objc(TodoListIntent)
public class TodoListIntent: INIntent {

    @NSManaged public var parameter: String?

}

/*!
 @abstract Protocol to declare support for handling a TodoListIntent. By implementing this protocol, a class can provide logic for resolving, confirming and handling the intent.
 @discussion The minimum requirement for an implementing class is that it should be able to handle the intent. The confirmation method is optional. The handling method is always called last, after confirming the intent.
 */
@available(iOS 12.0, macOS 11.0, watchOS 5.0, *) @available(tvOS, unavailable)
@objc(TodoListIntentHandling)
public protocol TodoListIntentHandling: NSObjectProtocol {

    @available(*, renamed: "confirm(intent:)")
    @objc(confirmTodoList:completion:)
    optional func confirm(intent: TodoListIntent, completion: @escaping (TodoListIntentResponse) -> Swift.Void)

    /*!
     @abstract Confirmation method - Validate that this intent is ready for the next step (i.e. handling)
     @discussion Called prior to asking the app to handle the intent. The app should return a response object that contains additional information about the intent, which may be relevant for the system to show the user prior to handling. If unimplemented, the system will assume the intent is valid, and will assume there is no additional information relevant to this intent.

     @param  intent The input intent
     @param  completion The response block contains a TodoListIntentResponse containing additional details about the intent that may be relevant for the system to show the user prior to handling.

     @see TodoListIntentResponse
     */
    @available(iOS 13.0, macOS 11.0, watchOS 6.0, *)
    @objc(confirmTodoList:completion:)
    optional func confirm(intent: TodoListIntent) async -> TodoListIntentResponse

    /*!
     @abstract Handling method - Execute the task represented by the TodoListIntent that's passed in
     @discussion Called to actually execute the intent. The app must return a response for this intent.

     @param  intent The input intent
     @param  completion The response handling block takes a TodoListIntentResponse containing the details of the result of having executed the intent

     @see  TodoListIntentResponse
     */
    @available(*, renamed: "handle(intent:)")
    @objc(handleTodoList:completion:)
    optional func handle(intent: TodoListIntent, completion: @escaping (TodoListIntentResponse) -> Swift.Void)
    
    @available(iOS 13.0, macOS 11.0, watchOS 6.0, *)
    @objc(handleTodoList:completion:)
    optional func handle(intent: TodoListIntent) async -> TodoListIntentResponse

}

/*!
 @abstract Constants indicating the state of the response.
 */
@available(iOS 12.0, macOS 11.0, watchOS 5.0, *) @available(tvOS, unavailable)
@objc public enum TodoListIntentResponseCode: Int {
    case unspecified = 0
    case ready
    case continueInApp
    case inProgress
    case success
    case failure
    case failureRequiringAppLaunch
}

@available(iOS 12.0, macOS 11.0, watchOS 5.0, *) @available(tvOS, unavailable)
@objc(TodoListIntentResponse)
public class TodoListIntentResponse: INIntentResponse {

    /*!
     @abstract The response code indicating your success or failure in confirming or handling the intent.
     */
    @objc public fileprivate(set) var code: TodoListIntentResponseCode = .unspecified

    /*!
     @abstract Initializes the response object with the specified code and user activity object.
     @discussion The app extension has the option of capturing its private state as an NSUserActivity and returning it as the 'currentActivity'. If the app is launched, an NSUserActivity will be passed in with the private state. The NSUserActivity may also be used to query the app's UI extension (if provided) for a view controller representing the current intent handling state. In the case of app launch, the NSUserActivity will have its activityType set to the name of the intent. This intent object will also be available in the NSUserActivity.interaction property.

     @param  code The response code indicating your success or failure in confirming or handling the intent.
     @param  userActivity The user activity object to use when launching your app. Provide an object if you want to add information that is specific to your app. If you specify nil, the system automatically creates a user activity object for you, sets its type to the class name of the intent being handled, and fills it with an INInteraction object containing the intent and your response.
     */
    @objc(initWithCode:userActivity:)
    public convenience init(code: TodoListIntentResponseCode, userActivity: NSUserActivity?) {
        self.init()
        self.code = code
        self.userActivity = userActivity
    }

}

#endif



이제 해야할 것 : 

 

1. TodoItem.swift 파일 생성

2. IntentHandler.swift 파일 생성

3. TodoListIntent.swift 파일 수정 → TodoList 파라미터 추가

4. Intent Definition 파일 수정  TodoList 파라미터를 추가