You are on page 1of 40

Input Method Kit Overview

Lee Collins
Manager, OS Engineering Asia
John Harvey
OS Engineering Asia

http://developer.apple.com/wwdc2006/
Developing Input Methods

• InputMethodKit
■ New framework for developing input methods
• Using keyboard layout overrides
• Data-driven input methods
• Delivery and installation
Input Method Kit
• Foundation-based API for input method development
• Easy to develop and port input method code
• Less code
■ 28 files in old sample
■ 8 files in IMKit sample
• Runs as background application
■ Separate address space
• No need for 64-bit work
• Fully integrated with TSM
• Carbon and Cocoa apps
Input Method Kit — Division of Labor
• IMKit manages
■ Communication with client apps
■ Candidate window

■ input method modes


• Developer supplies
■ Text from a conversion engine written in any programming
language
■ Key-bindings and optional event handling

■ Optional menu with additional settings

■ preferences settings
■ input mode specific commands
■ Information about input method in an extended info.plist
IMKit Classes

IMKServer

IMKInputController (1) IMKCandidates

IMKInputController (2)

IMKInputController (n)
IMKit Classes
• IMKServer
■ Manages client connections to your input method
■ Create in input method application’s main()

• IMKCandidates
■ Presents candidates to user
■ Notifies appropriate IMKInputController when a candidate has

been selected
• IMKInputController
■ Provides a base class for custom input controller classes
■ Events and text from application
■ Converted text from input method engine
■ One controller per input session created by the IMKServer object
IMKit: Handling Text Events
• Three different approaches
■ Keybinding: IMKit will map events to actions you implement
■ -(BOOL)inputText:(NSString*)string client:(id)sender;
■ -(BOOL)didCommandBySelector:(SEL)aSelector client:(id)sender;
■ Text data only
■ -(BOOL)inputText:(NSString*)string key:(NSInteger)keyCode modifiers:
(NSUInteger)flags client:(id)sender;
■ Handle all events
■ -(BOOL)handleEvent:(NSEvent*)event client:(id)sender;
IMKit: Candidate Window
• Candidates = list of alternate input choices
• Developer supplies candidate list
• IMKit handles display and selection
• 3 flavors of window:
■ Horizontal (kIMKSingleRowSteppingCandiatePanel)
■ Vertical (kIMKSingleColumnScrollingCandiatePanel)

■ Grid (kIMKScrollingGridCandidatePanel)
Using IMKCandidates
• In IMKInputController delegate or subclass, implement these:
■ -(NSArray*) candidates
■ supply candidate list to the IMKCandidates object
■ -(void) candidateSelected:(NSAttributedString*)string
■ Update your state when a candidate is selected

• Create an IMKCandidates object with preferred window shape


myCandidates = [[IMKCandidates alloc] initWithServer:server





panelType:kIMKSingleColumnScrollingCandidatePanel];

• Set and show the candidates


[myCandidates updateCandidates];
[myCandidates showCandidates:kIMKLocateCandidatesBelowHint];

• IMKit calls candidateSelected: when a candidate is selected


IMKit: Mode Support
• Means of packaging related input sources
■ E.g. Hiragana, Katakana and Romaji

• IMKit handes mode switching for you


■ Just provide mode information in plist
■ “ComponentInputModeDict”
■ IMKit tells you mode has been selected by sending
■ [ IMKInputController setValue:(id) value
forTag:(unsigned long) tag client:(id) sender ];
IMKit: plist Additions
• Add ComponentInputModeDict for modes
• Set LSBackgroundOnly to 1
<key> LSBackgroundOnly </key>
<string>1</string>

• Add InputMethodServerControllerClass key & value


■ Enables IMKServer to find your IMKController class
• Add the InputMethodConnectionName key & value
■ Enables IMKit framework to find your server
Input Method Hands On

http://developer.apple.com/wwdc2006/
Install the Project Template
• Install Template InputMethod Application in:
■ /Library/Application Support/Apple/Developer Tools/Project Templates/Application
• Open XCode
• Select New Project from File Menu
• Select Input Method Application
Create the Project
• Name the project Numbers
• Save it to /Users/Shared/Numbers/
Modifying the plist
• The Info.plist file has 6 important Keys(red required, green optional)
■ LSBackGroundOnly
■ Background applicatons don’t show in he Dock or Apple Menu.

■ InputMethodSessionController
■ Names your controller class.

■ InputMethodServerDelegateClass
■ Names your delegate class

■ ComponentInputModeDict
■ List your input method’s modes

■ InputMethodConnectionName
■ Names your server’s connection

■ tsInputMethodIconFileKey
■ Displayed in Text Input Menu and International Preferences

■ tsInputMethodCharacterRepertoire
■ Names ISO 15924 scripts your input method supports.
Controllers and Delegates
• What is a Controller object
■ Is in charge of something.
• What is a delegate
■ An object that implements a method declared in a protocol.
■ Exactly what kind of object implements the method is not
important.
• In the InputMethodKit. Your controller manages the buffer and
converting text. The Delegate receives text and handles specific
events.
• Delegate and Controller are not necessarily separate objects.
InputMethodSessionController
• Names your controller class
■ Necessary if you override IMKInputController
■ And you initialize IMKServer with:

-(id)initWithName:(NSString*)name bundleIdentifier:
(NSString*)bundleIdentifier
InputMethodServerDelegateClass
• This key names your delegate class.
■ Include this key if you provide a delegate class that implements
methods in the protocols defined in IMKInputController
■ IMKServerInput
■ IMKStateSetting
■ IMKMouseHandling
• Your controller class can also serve as you delegate class.
ComponentInputModeDict
• Include this dictionary if your input method includes input
modes.
■ For all the details read Tech Note 2128
■ <http://developer.apple.com/technotes/tn2005/tn2128.html>
■ An input method should include input modes when it uses
multiple ways of processing keyboard text input.
• Dictionary contains two keys
■ tsInputModeListKey
■ A dictionary which defines each mode.
■ tsVisibleInputModeOrderedArrayKey
■ Array of strings that define how your modes are displayed by the
System.
InputMethodConnectionName
• IMKServer uses this to create an NSConnection
■ Client applications communicate to the server via the named
NSConnection.
■ Do not include spaces in the name or periods.
■ Good

BasicInputMethodServer_1_Connection
■ Bad

BasicInputMethodServer.1.Connection

BasicInputMethodServer 1 Connection
tsInputMethodIconFileKey
• Name of the file that contains the icon used to display your
input method in the Text Input Menu or the International
Preferences Panel.

• The file itself is part of the Input Method’s bundle


tsInputMethodCharacterRepertoire
• List the ISO 15924 script codes that your input method supports
■ Alphabetical script codes.
■ http://www.unicode.org/iso15924/codelists.html
• This example indicates an input method that supports the Latin
script.

<key>tsInputMethodCharacterRepertoireKey</key>
<array>

<string>Latn</string>
</array>
Personalizing the Project
• Rename the controller class to NumbersInputController.[hm]
■ Be sure and rename the class interface inside the .h file.
@interface InputMethodSessionController

@interface NumbersInputController

■ The class implementation


@implementation InputMethodSessionController
@implementation NumbersInputController
■ Change #import as well.
#import "NumbersInputController.h"

#import "NumbersInputController.h"
• Open the Info.plist file
■ Change the string InputMethodSessionController to
NumbersInputController
<string>InputMethodSessionController</string>

<string>NumbersInputController</string>
Adding the Input Modes
• Our example looks for a number and then formats the number.
• Each type of formatting supported is an input mode.
• The modes are:
■ no style
■ decimal
■ currency
■ percent
■ spellout
• The modes are specified in the ComponentInputModeDict
• Open a modified ComponentInputModeDict
■ /Users/Shared/Beijing/Files/NumbersModeList.txt
• Copy every thing there and replace the old
ComponentInputModeDict and the old
tsVisibleInputModeOrderedArrayKey with what you copied.
tsVisibleInputModeOrderedArrayKey
• List of keys that are used to look up localizable strings.
• The localizable strings are located in the InfoPlist.strings file.
■ Open the Numbers InfoPlist.strings file.
■ Open /Users/Shared/Beijing/Files/NewModesStrings.txt
■ Replace the mode strings in InfoPlist.strings with the new strings.
Adding Your Icons
• For this example we have 6 icons
■ The Input Method Icon
■ The 6 mode icons
• Note that you still have the normal application icons that will be
seen in the Finder.
• In XCode add the .tiff files in /Users/Shared/Beijing/Images/
Icons.
• Put them in the Resources group.
■ You may want to add an Images group inside
Build Your Do Nothing Input Method
Getting Input
• The IMKServerInput informal protocol provides 3 different
approaches for receiving client input
■ Receive text as an NSString, and use keybinding to “parse” the
input context.
- (BOOL)inputText:(NSString*)string client:(id)sender;

■ Receive text as an NSString. The IMKServer extracts the context.


- (BOOL)inputText:(NSString*)string key:(NSInteger)keyCode
modifiers:(NSUInteger)flags client:(id)sender;

■ Receive events as NSEvents.


- (BOOL)handleEvent:(NSEvent*)event client:(id)sender;
Why Three Choices
• Three is a special number in the west.
• Seriously
■ We want to accommodate where different developers are coming
from.
■ -(BOOL)inputText:client:
■ The most Cocoa approach.

■ -(BOOL)inputText:key:modifiers:client:
■ Would like to see every keydown, but don’t really want to parse

NSEvents.
■ -(BOOL)handleEvent:client:
■ Porting an old component based input method.
Keybinding
• Modeled after the NSResponder class.
■ You can implement a method from a set of standard key event
handlers.
■ deleteBackward:
■ insertNewline:
■ See documentation for NSResponder for other action messages.
■ You can also specify your own keybinding in a dictionary.
■ InputMethodKeysDictionary.dict
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//
EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

<key>~ß</key>

<string>showAlternatives:</string>
</dict>
</plist>
Client Architecture
• Means you don’t need to manage input sessions.

• InputMethodKit maps clients to appropriate input controllers.

• One input controller is allocated for each input session.

• The sender parameter is used to communicate back to the


client.
IMKTextInput Protocol
• Used to communicate with the client application.
■ Send the message to the client parameter
■ i.e. [sender insertText:aString replacementRange:aRange];
• Sending Text
■ Formerly kEventTextInputUpdateActiveInputArea CarbonEvent

• Fix Text
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange;

• Mark Text
- (void)setMarkedText:(id)string selectionRange:(NSRange)selectionRange
replacementRange:(NSRange)replacementRange;
selectionRange & replacementRange
• selectionRange
■ Location is relative to the inline session.
document text 等きょう
selectionRange (4,0)

• replacementRange
■ Location is relative to the client document.
document text 等きょうmore document text
selectionRange (4,0)
replacementRange(13,0)

• Insert at current selection


■ Set replacementRange.location = NSNotFound
Positioning Methods
• Mapping a character index to screen position
(kEventTextInputOffsetToPos)
- (NSRect)firstRectForCharacterRange:(NSRange)theRange;

■ Returned rectangle contains screen relative coordinates


• Map screen position to character index
(kEventTextInputPosToOffset)
- (NSInteger)characterIndexForPoint:(NSPoint)point
tracking:(IMKLocationToOffsetMappingMode)mappingMode
inMarkedRange:(BOOL*)inMarkedRange

■ mappingMode
■ Set to IMKMouseTrackingMode when your input method is tracking
the mouse.
■ When placing the cursor set to IMKNearestBoundaryMode.
Overriding the Current Keyboard
• Your Input Method can contain keyboards
• To force the system to use your keyboard use:
-(void)overrideKeyboardWithKeyboardNamed:
(NSString*)keyboardUniqueName

• The keyboard name should be a DNS type name:


com.companyname.inputmethodname.keyboardname
Document Access Based Methods
• Document Access
■ Client document regarded as a CFStringRef
• Find the current selection.
- (NSRange)selectedRange

• Find the document length.


- (NSInteger)length

• Find an attributed string for a given range in the document.


- (NSAttributedString*)attributedSubstringFromRange:(NSRange)range;

• Not all clients support the Document access protocol


■ Be prepared for ranges of NSNotFound or a string value of nil.
Managing Global Resources
• What is a global resource?
■ Dictionary
■ Menu
■ UI Elements
■ Conversion Engine
• An IMKit input method is an application .
■ Global data
■ You may want to write or use a container object.
■ We will use the Application delegate object.
Sample Architecture

Global Resources contained in Application delegate

NSNumberFormater InputEngine
(conversion engine)

Multiple NumberInputControllers which access global resources.


These are managed by the IMKServer.

NumbersInputController NumbersInputController

NumbersInputController NumbersInputController
What We Need From You

Tell us where the InputMethodKit doesn’t meet your needs.

Contacts:
jharvey@apple.com
lcollins@apple.com
 Beijing Kitchen 2006

You might also like