Detecting current iPhone input language

Does anybody knows, can I get the current input language and/or keyboard layout in iPhone application? Can I also get a notification when input language was changed?


Solution 1:

In iOS 4.2 and later, you can use the UITextInputMode class to determine the primary language currently being used for text input.

[UITextInputMode currentInputMode].primaryLanguage will give you an NSString representing the BCP 47 language code such as “es”, “en-US”, or “fr-CA”.

You can register for the UITextInputCurrentInputModeDidChangeNotification to be alerted when the current input mode changes.

(You might also be interested in the "Getting Your Apps Ready for China and other Hot New Markets" WWDC session, and Internationalization Programming Topics.)

Solution 2:

You can ask current first responder (UITextField, UISearchBar, etc.) via UIResponder method textInputMode:

// assume you have instance variable pointing to search bar currently entering
UITextInputMode *inputMode = [self.searchBar textInputMode];
NSString *lang = inputMode.primaryLanguage;

Solution 3:

You can add an observer to the default notification center:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(inputModeDidChange:)
                                             name:@"UIKeyboardCurrentInputModeDidChangeNotification"
                                           object:nil];

This method prints the currently selected input language (like "en_US" or "de_DE"):

- (void)inputModeDidChange:(NSNotification*)notification
{
    id obj = [notification object];
    if ([obj respondsToSelector:@selector(inputModeLastUsedPreference)]) {
        id mode = [obj performSelector:@selector(inputModeLastUsedPreference)];
        NSLog(@"mode: %@", mode);
    }
}

BUT: All the above is not documented and you should not use it in shipping code!

Solution 4:

From the Apple Reference Library - "Getting the Current Language and Locale":

NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];

Solution 5:

In line with the top answers, the following is a generic solution to getting the keyboard language whenever it is changed. Register for the notification UITextInputCurrentInputModeDidChangeNotification:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inputModeDidChange:) name:UITextInputCurrentInputModeDidChangeNotification object:nil];

Then in inputModeDidChange

-(void)inputModeDidChange:(NSNotification *)notification {
   UIView *firstResponder = [UIView currentFirstResponder];
   UITextInputMode *currentInputMode =  firstResponder.textInputMode;
   NSString *keyboardLanguage = [currentInputMode primaryLanguage];
   NSLog(@"%@", keyboardLanguage); // e.g. en-US
}

Where currentFirstResponder is from a category on UIView to get the first responder view, as suggested in this SO post:

//  UIView+Additions.h 
#import <UIKit/UIKit.h>
@interface UIView (Additions)
+ (id)currentFirstResponder;
@end

Implementation

//  UIView+Additions.m
#import "UIView+Additions.h"
static __weak id currentFirstResponder;
@implementation UIView (Additions)
+ (id)currentFirstResponder {
    currentFirstResponder = nil;
    // This will invoke on first responder when target is nil
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:)
                                           to:nil
                                         from:nil
                                     forEvent:nil];
    return currentFirstResponder;
}

- (void)findFirstResponder:(id)sender {
    // First responder will set the static variable to itself
    currentFirstResponder = self;
}
@end