Our Blog

Related Posts

Chrome has a new feature that makes it easy to test how a website will look on different mobile phones and tablets. See our How-To video here.

Popular Tags

Recent Comments

Brendon Carvalho
4.26.2018 - MSSQL Long Text Field Truncated In PHP
Hire Volusion Developers
4.7.2018 - Drupal 8 Roadmap

Ben Young

With the release of iOS 8 Apple has finally added the ability for integration of third-party keyboards such as Swype and SwiftKey. This is a great thing, but as an iOS app developer it has the potential to complicate things.

For example, Pixo recently began receiving complaints from users of our Vehicle Barcode Scanner app on iOS about issues they were having with the keyboard in our application. The problem turned out to be that one input field in our application was not interacting well with third-party keyboards. When a user manually enters a VIN our app provides a customized keyboard view that limits input to characters that are valid in a VIN:

customized iOS keyboard

Users who had installed a third-party keyboard were seeing something like the following image:

third-party iOS swiftkey keyboard

Pixo’s custom keyboard is implemented as a ViewController assigned to the inputView property of the associated UITextField. The third-party keyboard isn’t aware that another custom inputView is being displayed, so it will appear along with our custom inputView.

There turns out to be a straightforward solution to this issue that was added as part of the iOS 8 API: the UIApplicationDelegate protocol’s shouldAllowExtensionPointIdentifier method:

- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString *)extensionPointIdentifier

In fact the only extension point identifier currently available is the custom keyboard extension point, identified by UIApplicationKeyboardExtensionPointIdentifier. So the simplest way to work around the problem is to include the following in the UIApplicationDelegate:

- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString *)extensionPointIdentifier
  {
    if ([extensionPointIdentifier isEqualToString: UIApplicationKeyboardExtensionPointIdentifier])
    {
      return NO;
    }
    return YES;
 }

However, this solution will block the use of third-party keyboards in any input fields in our entire application, which isn’t what we want. A better solution would be to disable third-party keyboards only for input field(s) that we know will have problems. The shouldAllowExtensionPointIdentifier method is called each time the keyboard is displayed, so as long as we can identify the current input field we will be able to block third-party keyboards selectively.The first step is to determine which field is the applications First Responder. In the past there were simple methods available to do this, but they have been moved into private APIs and using them can cause your application to be rejected from the app store. However, there is another simple trick that will let you identify the First Responder. If you send a selector action to a nil object reference, that selector is instead routed to your applications First Responder. The following snippet sends a selector action to nil, and returns a reference to the object that runs the selector, which should always be the First Responder.

id firstResponder;
-(id)findFirstResponder {
  firstResponder = nil;
  [[UIApplication sharedApplication] sendAction:@selector(foundFirstResponder:) to:nil forEvent:nil];
  return firstResponder;
}
-(void)foundFirstResponder:(id)sender {
  firstResponder = self;
}

Now that we have a way to find the first responder, the final step is to update our shouldAllowExtensionPointIdentifier implementation so that it will only block third-party keyboards for specific input fields. In our case, we check for our specific inputView assigned to a UITextField, which looks something like this:


- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString *)extensionPointIdentifier {
  if ([extensionPointIdentifier isEqualToString: UIApplicationKeyboardExtensionPointIdentifier])
  {
    id responder = [self findFirstResponder];
    if ([responder isKindOfClass:[UITextField class]])
    {
      if ([((UITextField *)responder).inputView isKindOfClass:[VinKeyboardView class]])
      {
        return NO;
      }
    }
  }
  return YES;
}

Of course you will need to adjust your implementation to support the specific needs of your own application.

Now third-party iOS keyboards will no longer fight with your application’s custom keyboards but will be accessible everywhere else. Everyone wins!

Related Posts

Chrome has a new feature that makes it easy to test how a website will look on different mobile phones and tablets. See our How-To video here.

Recent Comments

Brendon Carvalho
4.26.2018 - MSSQL Long Text Field Truncated In PHP
Hire Volusion Developers
4.7.2018 - Drupal 8 Roadmap

Interested in working with us?
CONTACT US