Is it possible to "toggle software keyboard" via the code in UI test? Is it possible to "toggle software keyboard" via the code in UI test? ios ios

Is it possible to "toggle software keyboard" via the code in UI test?


Tested in Xcode 10.3 & Xcode 11. The snippet below needs to be located in the app target (not the test bundle) — for instance, in AppDelegate.swift. It will disable any hardware keyboards from automatically connecting by setting any UIKeyboardInputMode's automaticHardwareLayout properties to nil.

🔥 Does not depend on the settings of the Simulator.

#if targetEnvironment(simulator)// Disable hardware keyboards.let setHardwareLayout = NSSelectorFromString("setHardwareLayout:")UITextInputMode.activeInputModes    // Filter `UIKeyboardInputMode`s.    .filter({ $0.responds(to: setHardwareLayout) })    .forEach { $0.perform(setHardwareLayout, with: nil) }#endif

Or Objective-C:

#if TARGET_IPHONE_SIMULATORSEL setHardwareLayout = NSSelectorFromString(@"setHardwareLayout:");for (UITextInputMode *inputMode in [UITextInputMode activeInputModes]) {    if ([inputMode respondsToSelector:setHardwareLayout]) {        // Note: `performSelector:withObject:` will complain, so we have to use some black magic.        ((void (*)(id, SEL, id))[inputMode methodForSelector:setHardwareLayout])(inputMode, setHardwareLayout, NULL);    }}#endif


The simulator's .plist file changed to add support for multiple simulators. The ConnectHardwareKeyboard boolean is now nested underneath the device's UDID. Luckily this UDID is also stored in the plist file. You can add this code using 'run script' under your UITest target's build phases.

Xcode 9 answer:

#grab the UDID from the plistUDID=$(defaults read com.apple.iphonesimulator CurrentDeviceUDID)#overwrite the existing value with false#OR if the plist doesn't have that value add it in/usr/libexec/PlistBuddy -c "Set :DevicePreferences:$UDID:ConnectHardwareKeyboard false" ~/Library/Preferences/com.apple.iphonesimulator.plist || /usr/libexec/PlistBuddy -c  "Add :DevicePreferences:$UDID:ConnectHardwareKeyboardbool false" ~/Library/Preferences/com.apple.iphonesimulator.plist

Or you can use this other code to affect all simulators:

/usr/libexec/PlistBuddy -c "Print :DevicePreferences" ~/Library/Preferences/com.apple.iphonesimulator.plist | perl -lne 'print $1 if /^    (\S*) =/' | while read -r a; do /usr/libexec/PlistBuddy -c "Set :DevicePreferences:$a:ConnectHardwareKeyboardfalse" ~/Library/Preferences/com.apple.iphonesimulator.plist || /usr/libexec/PlistBuddy -c  "Add :DevicePreferences:$a:ConnectHardwareKeyboardbool false" ~/Library/Preferences/com.apple.iphonesimulator.plist; done


Prior to Xcode 9, you can work around this by disabling the hardware keyboard in Simulator.app which will cause the software keyboard to always be present. Eg:

defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool NO