Expand Minimize Picture-in-picture Power Device Status Voice Recognition Skip Back Skip Forward Minus Plus Play Search
Internet Explorer alert
This browser is not recommended for use with smartdevicelink.com, and may not function properly. Upgrade to a different browser to guarantee support of all features.
close alert
To Top Created with Sketch. To Top
To Bottom Created with Sketch. To Bottom
iOS Guides
Popup Keyboards

Popup Keyboards

Presenting a keyboard or a popup menu with a search field requires you to implement the SDLKeyboardDelegate. Note that the initialText in the keyboard case often acts as "placeholder text" and not as true initial text.

Presenting a Keyboard

You should present a keyboard to users when your app contains a "search" field. For example, in a music player app, you may want to give the user a way to search for a song or album. A keyboard could also be useful in an app that displays nearby points of interest, or in other situations.

Note

Keyboards are unavailable for use in many countries when the driver is distracted. This is often when the vehicle is moving above a certain speed, such as 5 miles per hour. This will be automatically managed by the system. Your keyboard may be disabled or an error returned if the driver is distracted.

Keyboard Search

// Returns a cancelID and presents the keyboard
NSNumber<SDLInt> *cancelID = [self.sdlManager.screenManager presentKeyboardWithInitialText:<#(nonnull NSString *)#> delegate:<#(nonnull id<SDLKeyboardDelegate>)#>];
// Returns a cancelID and presents the keyboard
let cancelID = sdlManager.screenManager.presentKeyboard(withInitialText: <#String#>, delegate: <#SDLKeyboardDelegate#>)

Implementing the Keyboard Delegate

Using the SDLKeyboardDelegate is required for popup keyboards and popup menus with search. It involves two required methods (for handling the user's input and the keyboard's unexpected abort), as well as several optional methods for additional functionality.

#pragma mark - SDLKeyboardDelegate

/// Required Methods
- (void)keyboardDidAbortWithReason:(SDLKeyboardEvent)event {
    if ([event isEqualToEnum:SDLKeyboardEventCancelled]) {
        <#The user cancelled the keyboard interaction#>
    } else if ([event isEqualToEnum:SDLKeyboardEventAborted]) {
        <#The system aborted the keyboard interaction#>
    }
}

- (void)userDidSubmitInput:(NSString *)inputText withEvent:(SDLKeyboardEvent)source {
    if ([source isEqualToEnum:SDLKeyboardEventSubmitted]) {
        <#The user submitted some text with the keyboard#>
    } else if ([source isEqualToEnum:SDLKeyboardEventVoice]) {
        <#The user decided to start voice input, you should start an AudioPassThru session if supported#>
    }
}

/// Optional Methods
- (void)updateAutocompleteWithInput:(NSString *)currentInputText autoCompleteResultsHandler:(SDLKeyboardAutoCompleteResultsHandler)resultsHandler {
    <#Check the input text and return an array of autocomplete results#>
    resultsHandler(@[<#String results to be displayed#>]);
}

- (void)updateCharacterSetWithInput:(NSString *)currentInputText completionHandler:(SDLKeyboardCharacterSetCompletionHandler)completionHandler {
    <#Check the input text and return a set of characters to allow the user to enter#>
}

- (void)keyboardDidSendEvent:(SDLKeyboardEvent)event text:(NSString *)currentInputText {
    <#This is sent upon every event, such as keypresses, cancellations, and aborting#>
}

- (SDLKeyboardProperties *)customKeyboardConfiguration {
    <#Use an alternate keyboard configuration. The keypressMode, limitedCharacterSet, and autoCompleteText will be overridden by the screen manager#>
}
extension <#Class Name#>: SDLKeyboardDelegate {
    /// Required Methods
    func keyboardDidAbort(withReason event: SDLKeyboardEvent) {
        switch event {
        case .cancelled:
            <#The user cancelled the keyboard interaction#>
        case .aborted:
            <#The system aborted the keyboard interaction#>
        default: break
        }
    }

    func userDidSubmitInput(_ inputText: String, withEvent source: SDLKeyboardEvent) {
        switch source {
        case .voice:
            <#The user decided to start voice input, you should start an AudioPassThru session if supported#>
        case .submitted:
            <#The user submitted some text with the keyboard#>
        default: break
        }
    }

    /// Optional Methods
    func updateAutocomplete(withInput currentInputText: String, autoCompleteResultsHandler resultsHandler: @escaping SDLKeyboardAutoCompleteResultsHandler) {
        <#Check the input text and return an array of autocomplete results#>
        resultsHandler([<#String results to be displayed#>]);
    }

    func updateCharacterSet(withInput currentInputText: String, completionHandler: @escaping SDLKeyboardCharacterSetCompletionHandler) {
        <#Check the input text and return a set of characters to allow the user to enter#>
    }

    func keyboardDidSendEvent(_ event: SDLKeyboardEvent, text currentInputText: String) {
        <#This is sent upon every event, such as keypresses, cancellations, and aborting#>
    }

    func customKeyboardConfiguration() -> SDLKeyboardProperties {
        <#Use an alternate keyboard configuration. The keypressMode, limitedCharacterSet, and autoCompleteText will be overridden by the screen manager#>
    }

    func keyboardDidUpdateInputMask(_ isEnabled: Bool) {
        if isEnabled {
            <#The user turned on masking the input#>
        } else {
            <#The user turned off masking the input#>
        }
    }
}

Configuring Keyboard Properties

You can change default keyboard properties by updating sdlManager.screenManager.keyboardConfiguration. If you want to change the keyboard configuration for only one keyboard session and keep the default keyboard configuration unchanged, you can implement the customKeyboardConfiguration delegate method and pass back the single-use KeyboardProperties for that given keyboard presentation.

Keyboard Language

You can modify the keyboard language by changing the keyboard configuration's language. For example, you can set an EN_US keyboard. It will default to EN_US if not otherwise set.

SDLKeyboardProperties *keyboardConfiguration = [[SDLKeyboardProperties alloc] init];
keyboardConfiguration.language = SDLLanguageEnUs;

self.sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration;
let keyboardConfiguration = SDLKeyboardProperties()
keyboardConfiguration.language = .enUs

sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration

Limited Character List

You can modify the keyboard to enable only some characters by responding to the updateCharacterSet:completionHandler: delegate method or by changing the keyboard configuration before displaying the keyboard. For example, you can enable only "a", "b" , and "c" on the keyboard. All other characters will be greyed out (disabled).

SDLKeyboardProperties *keyboardConfiguration = [[SDLKeyboardProperties alloc] init];
keyboardConfiguration.limitedCharacterList = @[@"a", @"b", @"c"];

self.sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration;
let keyboardConfiguration = SDLKeyboardProperties()
keyboardConfiguration.limitedCharacterList = ["a", "b", "c"]

sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration

Autocomplete List

You can modify the keyboard to allow an app to pre-populate the text field with a list of suggested entries as the user types by responding to the updateAutocompleteWithInput:autoCompleteResultsHandler: delegate method or by changing the keyboard configuration before displaying the keyboard. For example, you can display recommended searches "test1", "test2", and "test3" if the user types "tes".

Note

A list of autocomplete results is only available on RPC 6.0+ connections. On connections < RPC 6.0, only the first item will be available to the user.

SDLKeyboardProperties *keyboardConfiguration = [[SDLKeyboardProperties alloc] init];
keyboardConfiguration.autoCompleteList = @[@"test1", @"test2", @"test3"];

self.sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration;
let keyboardConfiguration = SDLKeyboardProperties()
keyboardConfiguration.autoCompleteList = ["test1", "test2", "test3"]

sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration

Keyboard Layout

You can modify the keyboard layout by changing the keyboard configuration's keyboardLayout. For example, you can set a NUMERIC keyboard. It will default to QWERTY if not otherwise set.

Note

The numeric keyboard layout is only available on RPC 7.1+. See the section Checking Keyboard Capabilities to determine if this layout is available.

Numeric Keyboard

SDLKeyboardProperties *keyboardConfiguration = [[SDLKeyboardProperties alloc] init];
keyboardConfiguration.keyboardLayout = SDLKeyboardLayoutNumeric;

self.sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration;
let keyboardConfiguration = SDLKeyboardProperties()
keyboardConfiguration.keyboardLayout = .numeric

sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration

Input Masking (RPC 7.1+)

You can modify the keyboard to mask the entered characters by changing the keyboard configuration's maskInputCharacters.
Numeric Keyboard

SDLKeyboardProperties *keyboardConfiguration = [[SDLKeyboardProperties alloc] init];
keyboardConfiguration.keyboardLayout = SDLKeyboardLayoutNumeric;
keyboardConfiguration.maskInputCharacters = SDLKeyboardInputMaskEnableInputKeyMask;

self.sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration;
let keyboardConfiguration = SDLKeyboardProperties()
keyboardConfiguration.keyboardLayout = .numeric
keyboardConfiguration.maskInputCharacters = .enableInputKeyMask

sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration

Custom Keys (RPC 7.1+)

Each keyboard layout has a number of keys that can be customized to your app's needs. For example, you could set two of the customizable keys in QWERTY layout to be "!" and "?" as seen in the image below. The available number and location of these custom keys is determined by the connected head unit. See the section Checking Keyboard Capabilities to determine how many custom keys are available for any given layout.

Custom Keys

SDLKeyboardProperties *keyboardConfiguration = [[SDLKeyboardProperties alloc] init];
keyboardConfiguration.keyboardLayout = SDLKeyboardLayoutQWERTY;
keyboardConfiguration.customKeys = @[@"!", @"?"];

self.sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration;
let keyboardConfiguration = SDLKeyboardProperties()
keyboardConfiguration.keyboardLayout = .qwerty
keyboardConfiguration.customKeys = ["!", "?"]

sdlManager.screenManager.keyboardConfiguration = keyboardConfiguration

Checking Keyboard Capabilities (RPC v7.1+)

Each head unit may support different keyboard layouts and each layout can support a different number of custom keys. Head units may not support masking input. If you want to know which keyboard features are supported on the connected head unit, you can check the KeyboardCapabilities:

SDLKeyboardCapabilities *keyboardCapabilities = self.sdlManager.systemCapabilityManager.defaultMainWindowCapability.keyboardCapabilities;

// List of layouts and number of custom keys supported by each layout or `nil` if no capabilities are available
NSArray<SDLKeyboardLayoutCapability *> *keyboardLayoutCapabilities = keyboardCapabilities.supportedKeyboards;

// Boolean represents whether masking is supported or not
BOOL maskInputSupported = keyboardCapabilities.maskInputCharactersSupported.boolValue;
guard let keyboardCapabilities = sdlManager.systemCapabilityManager.defaultMainWindowCapability?.keyboardCapabilities else { return }

// List of layouts and number of custom keys supported by each layout or `nil` if no capabilities are available
let keyboardLayoutCapabilities = keyboardCapabilities.supportedKeyboards

// Boolean represents whether masking is supported or not
let maskInputSupported = keyboardCapabilities.maskInputCharactersSupported?.boolValue

Dismissing the Keyboard (RPC v6.0+)

You can dismiss a displayed keyboard before the timeout has elapsed by sending a CancelInteraction request. If you presented the keyboard using the screen manager, you can dismiss the choice set by calling dismissKeyboard with the cancelID that was returned (if one was returned) when presenting.

Note

If connected to older head units that do not support this feature, the cancel request will be ignored, and the keyboard will persist on the screen until the timeout has elapsed or the user dismisses it by making a selection.

// Use the saved cancelID from above to dismiss the keyboard
[self.sdlManager.screenManager dismissKeyboardWithCancelID:cancelID];
// Use the saved cancelID from above to dismiss the keyboard
sdlManager.screenManager.dismissKeyboard(withCancelID: cancelID)

Using RPCs

If you don't want to use the SDLScreenManager, you can do this manually using the PerformInteraction RPC request. As this is no longer a recommended course of action, we will leave it to you to figure out how to manually do it.

Note that if you do manually create a PerformInteraction and want to set a cancel id, the SDLScreenManager takes cancel ids 0 - 10000. Any cancel id you set must be outside of that range.

View on GitHub.com
Previous Section Next Section