30

EDIT: tl;dr - it is possible, see accepted answer below.

Is there any (not only programatic) way of preventing custom keyboards (iOS8) from being used for my application? I am mainly interested in "per-app" setting, so just my app is not allowed to use custom keyboards, but disabling custom keyboards system-wide is last resort.

So far I know that custom keyboards are system-wide and can be used by any application. The OS will fallback to stock keyboard only for secure text entry (text fields with secureTextEntry set to YES). Not much hope here.

I got an impression from App Extension Programming Guide that MDM (Mobile Device Management) can restrict device from using custom keyboards at all, but I didn't find that option in the new beta version of Apple Configurator.app for OS X Yosemite. Is 'Configurator' just missing that option?

Any ideas here? Should I file a radar to suggest that Apple should introduce such functionality?

matm
  • 7,059
  • 5
  • 36
  • 50
  • 2
    If a users want to use a custom keyboard, who are you to stop them? – Filip Radelic Jul 03 '14 at 15:36
  • 2
    @FilipRadelic: security reasons (enterprise app). – matm Jul 03 '14 at 20:14
  • 1
    @matm - AFAIK you cannot do that. Custom keyboards "replace" the system keyboard on a system-wide base. The only thing you can do from an enterprise perspective is to a) disallow the installation of App Store apps or b) execute some actions if someone has installed an app that includes a custom keyboard. But a) is hard to implement in BYOD and b) is hard to find... Apple is open to radars (maybe for iOS9) then. – muenzpraeger Jul 04 '14 at 11:39

5 Answers5

56

Looks like you got what you wanted in beta seed 3. Line 440 of UIApplication.h:

// Applications may reject specific types of extensions based on the extension point identifier.
// Constants representing common extension point identifiers are provided further down.
// If unimplemented, the default behavior is to allow the extension point identifier.
- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString *)extensionPointIdentifier NS_AVAILABLE_IOS(8_0);

It's not currently included in the docs, but sound like it will do exactly what you asked here.

I'm guessing these "extension point identifiers" are not unique identifiers of extensions, but of their types, as there is also this on line 545:

// Extension point identifier constants
UIKIT_EXTERN NSString *const UIApplicationKeyboardExtensionPointIdentifier NS_AVAILABLE_IOS(8_0);

TLDR: to disable custom keyboards you would include something like this in your app delegate:

- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString *)extensionPointIdentifier {
    if ([extensionPointIdentifier isEqualToString: UIApplicationKeyboardExtensionPointIdentifier]) {
        return NO;
    }
    return YES;
}
Filip Radelic
  • 26,607
  • 8
  • 71
  • 97
  • This is great news! I was about to go through API diffs today and have one more reason to do that :) Thanks for sharing! – matm Jul 09 '14 at 06:27
  • @Filip: Thanks for the answer. But I have another problem. I know that we will be able to disable custom iOS 8 keyboards using above code snippet. The important point here is that we need to use Xcode-6/iOS 8 SDK to use the above. I am still on Xcode 5 due to some other limitations. Is there any way I can prevent the third party keyboards using iOS 7 SDK/Xcode 5? Please Help. – Rashmi Ranjan mallick Oct 29 '14 at 14:07
  • @RashmiRanjanmallick theoretically, there's nothing stopping you from implementing this method when compiling against older SDK. You would just have to replace `UIApplicationKeyboardExtensionPointIdentifier` constant since it's not defined prior to 8.0 SDK. You can just replace it with `@"com.apple.keyboard-service"`. However, I have no idea if that method will actually get called on iOS 8 when built against older SDK and I don't have any older SDK to try so let me know if it works for you. – Filip Radelic Oct 29 '14 at 15:06
  • Thanks for this nice idea !! I will try and let you know – Rashmi Ranjan mallick Oct 29 '14 at 17:45
  • 2
    FYI -- that does indeed work in iOS 7 SDK. (tested) In fact... it even works in iOS 6 SDK. (tested) – RedRedSuit Feb 26 '15 at 19:29
  • 1
    when I tried the above code, it worked. But when I added some if condition, it return NO and still show 3rd party keyboard. Can anyone help? – DianeZhou May 07 '16 at 08:50
10

Swift 3 :

func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplicationExtensionPointIdentifier) -> Bool {
    if extensionPointIdentifier == UIApplicationExtensionPointIdentifier.keyboard {
        return false
    }
    return true
}
wuf810
  • 633
  • 12
  • 19
6

I just want to add this for those developers who want to implement this method in Xamarin iOS. The idea is to override theShouldAllowExtensionPointIdentifier method in your AppDelegate:

public override bool ShouldAllowExtensionPointIdentifier(UIApplication application, NSString extensionPointIdentifier)
{
    if (extensionPointIdentifier == UIExtensionPointIdentifier.Keyboard) 
    {           
        return false;
    }
    return true;
}
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Sugat
  • 262
  • 5
  • 11
2

In Swift 5, UIApplicationExtensionPointIdentifier was changed to UIApplication.ExtensionPointIdentifier.

func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplication.ExtensionPointIdentifier) -> Bool {
    if extensionPointIdentifier == UIApplication.ExtensionPointIdentifier.keyboard {
        return false
    }
    return true
}
0

In Swift 5 using a switch:

func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplication.ExtensionPointIdentifier) -> Bool {
    switch extensionPointIdentifier {
        case .keyboard:
            return false
        default:
            return true
    }
}