본문 바로가기
Swfit/WidgetKit

Configurable Widget Keyboard type 설정하기 (iOS 17 & above)

by GGShin 2024. 2. 4.

사용자 설정이 가능한 Widget은 수정을 허용하는 파라미터의 타입에 따라서 자동적으로 알맞는 키보드를 보여줍니다.

만일 파라미터가 Int 타입이라면 number pad 키보드를, String 타입이라면 text 키보드를 보여줍니다. 

(원시 타입이 아니라 Dynamic option을 사용할 수도 있습니다. 이 경우는 몇 가지 선택을 사용자가 할 수 있도록 drop down 옵션을 보여주는 데 나중에 제가 직접 사용해 보고 올려보도록 하겠습니다.)

 

String type을 사용했을 때 기본적으로 자판이 영문만 지원이 되는 데, 어떻게 키보드를 바꾸어야 하는 지 한참을 헤맸었습니다. 한국어나 이모지도 쓸 수가 없고 정말 영문만 타이핑 할 수 있는 자판이 나왔습니다.

iOS 16 under 버전들의 Siri Intent는 GUI에서 체크박스 선택을 해주면 되었는데, AppIntents에서는 어떻게 설정 해주면 좋은 지 한 번에 찾지 못했었습니다. 다행히 AppIntents 코드를 보다가 KeyboardType를 보게 되었고 제가 찾고 찾았던 부분임을 직감할 수 있었습니다. String extension 내부 IntentInputOptions struct에 선언이 되어 있는데, 그렇다면 어떻게 이 옵션을 설정해 주면 될까요?

 

@available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
extension String {

    public struct IntentInputOptions {

        /// Describes the types of keyboard to use for text entry.
        public enum KeyboardType {

            @available(macOS 13.0, iOS 16.1, watchOS 9.1, tvOS 16.1, *)
            case `default`

            /// A keyboard that displays standard ASCII characters.
            case asciiCapable

            /// A keyboard that displays numbers and punctuation.
            case numbersAndPunctuation

            /// A keyboard that provides URL entry.
            case URL

            /// A numeric keypad.
            case numberPad
			
            /// ...
        }

        /// Describes the capitalization modes to apply to text.
        public enum CapitalizationType {

            /// A mode that applies no automatic capitalization.
            case none

            /// A mode that capitalizes the first letter of each word.
            case words

            /// A mode that capitalizes the first letter of each sentence.
            case sentences

            /// A mode that capitalizes all characters.
            case allCharacters
			
            // ... 
        }

        public var keyboardType: String.IntentInputOptions.KeyboardType

        public var capitalizationType: String.IntentInputOptions.CapitalizationType

        public var multiline: Bool

        public var autocorrect: Bool

        public var smartQuotes: Bool

        public var smartDashes: Bool

        public init(keyboardType: String.IntentInputOptions.KeyboardType = .asciiCapable, capitalizationType: String.IntentInputOptions.CapitalizationType = .sentences, multiline: Bool = false, autocorrect: Bool = true, smartQuotes: Bool = true, smartDashes: Bool = true)
    }
}

 

옵션은 바로 intent의 parameter attribute 선언 시에 설정해 줄 수 있습니다.

코드로 보면, 사용자 수정 허용 항목에 @Parameter라는 attribute를 붙여주어야 합니다. 이때, attribute의 arguments 중 inputOptions가 있는데, 이 부분에 원하는 옵션을 설정해주면 되는 것입니다. 

struct SomeAppIntent: WidgetConfigurationIntent {
    static var intentClassName: String = "SomeAppIntentClass"
    
    static var title: LocalizedStringResource = "SomeAppIntentTitle"
   
   // Parameter attribute에서 설정!
    @Parameter(title: "Some Title", inputOptions: String.IntentInputOptions(keyboardType: .default, autocorrect: false))
    var sentence: String?
    //...
  }

 

 

InputOptions의 이니셜라이져에 기본적으로 값들이 설정되어 있기 때문에, 따로 옵션 값들을 조정해주지 않는다면 기본 값으로 적용되게 됩니다. 보면 KeyboardType에 .asciiCapable로 되어 있는데, 이 부분을 .default로 변경해주었습니다. 그랬더니 영문 자판 뿐만 아니라, 한국어, 이모지 등등 사용자가 기본적으로 설정해서 사용하던 키보드를 사용할 수 있도록 바뀌게 되었습니다.

 

Widget을 개발하시는 분들께 꼭 도움이 되었으면 좋겠습니다 :D

반응형