swype - ¿Cómo funciona el teclado iOS personalizado de Google, Gboard, descartando programáticamente la aplicación principal?
teclado swype para iphone gratis (1)
La aplicación de iOS personalizada de Google, Gboard , tiene una característica interesante que no se puede lograr usando API públicas en el iOS SDK (a partir de iOS 10). Me gustaría saber exactamente cómo Google cumple la tarea de mostrar de forma programada una aplicación en la pila de cambio de aplicación en Gboard.
Los teclados personalizados de iOS tienen dos componentes principales: la aplicación de contenedor y la extensión de aplicación de teclado. La extensión de la aplicación de teclado se ejecuta en un proceso de sistema operativo independiente que se inicia cada vez que un usuario se encuentra en cualquier aplicación de su teléfono que requiera ingreso de texto.
Estos son los pasos aproximados que se pueden seguir, usando Gboard, para ver el efecto de volver programáticamente a una aplicación anterior:
- Un usuario inicia la aplicación Messages Apple en su iPhone y toca un campo de texto para comenzar a ingresar texto.
- Se inicia la extensión de teclado de Gboard y los usuarios ven el teclado personalizado de Gboard (mientras todavía están en la aplicación Mensajes de Apple).
- El usuario toca la tecla del micrófono dentro de la extensión del teclado Gboard para hacer la entrada de voz a texto.
- Gboard utiliza un esquema de URL personalizado para iniciar la aplicación de contenedor Gboard. El teclado Gboard y la aplicación de mensajes de Apple se presionan hacia abajo una capa en la pila de aplicaciones y la aplicación de contenedor Gboard es ahora la aplicación más avanzada en la pila de aplicaciones. La aplicación de contenedor Gboard utiliza el micrófono para escuchar el discurso del usuario y lo traduce en texto que coloca en la pantalla.
- El usuario toca el botón "Listo" cuando están satisfechos con la entrada de texto que ven en la pantalla.
- Aquí es donde ocurre la magia ... a medida que la pantalla de entrada de texto se descarta, la aplicación de contenedor Gboard también se descarta automáticamente. La aplicación de contenedor Gboard desaparece y es reemplazada por la aplicación Apple Messages (algunas veces el proceso de extensión del teclado Gboard aún está activo, algunas veces se relanza y algunas veces necesita reiniciarse manualmente tocando dentro de un campo de texto). ¿Cómo logra Google esto?
- Finalmente, el usuario ve el texto que acaba de traducir insertarse automáticamente dentro del campo de entrada de texto. Es de suponer que Google logra esto compartiendo datos entre la aplicación de contenedor Gboard y la extensión del teclado.
Supongo que Google está utilizando API privadas explorando la jerarquía de vistas de la barra de estado utilizando la introspección de tiempo de ejecución de Objective-C y de alguna manera sintetizando eventos tap o llamando a un objetivo / acción expuesta. He explorado esto muy poco y he podido encontrar subclases UIView interesantes dentro de la barra de estado, como UIStatusBarBreadcrumbItemView que contiene una matriz de UISystemNavigationAction s. Continúo explorando estas clases con la esperanza de encontrar una forma de replicar la interacción del usuario.
Entiendo que el uso de API privadas es una buena manera de que se rechace el envío de su aplicación desde App Store; esta no es una preocupación que me gustaría abordar en la respuesta. Estoy buscando principalmente respuestas específicas sobre cómo exactamente Google logra la tarea de mostrar de forma programada una aplicación en la pila de cambio de aplicaciones en Gboard.
Su suposición es correcta: Gboard está utilizando una API privada para hacerlo.
... aunque no a través de la exploración de la jerarquía de vistas o la inyección de eventos.
Cuando se realiza la acción de voz a texto, podemos verificar el registro del sistema desde Xcode o la consola que llama el -[AVAudioSession setActive:withOptions:error:]
. Así que modifiqué la aplicación Gboard y busqué el seguimiento de la pila relacionado con esto.
Al subir la pila de llamadas, podemos encontrar el método -[GKBVoiceRecognitionViewController navigateBackToPreviousApp]
, y ...
…_systemNavigationAction? Sí, definitivamente API privada.
Como class_getInstanceVariable
es una API pública y "_systemNavigationAction"
es una cadena literal, el verificador automático no puede observar el uso privado de la API, y los revisores humanos probablemente no vean nada incorrecto con el comportamiento de "volver a la aplicación anterior" . O probablemente porque son Google y tú no ...
El código real que realiza la acción "saltar de vuelta a la aplicación anterior" es así:
@import UIKit;
@import ObjectiveC.runtime;
@interface UISystemNavigationAction : NSObject
@property(nonatomic, readonly, nonnull) NSArray<NSNumber*>* destinations;
-(BOOL)sendResponseForDestination:(NSUInteger)destination;
@end
inline BOOL jumpBackToPreviousApp() {
Ivar sysNavIvar = class_getInstanceVariable(UIApplication.class, "_systemNavigationAction");
UIApplication* app = UIApplication.sharedApplication;
UISystemNavigationAction* action = object_getIvar(app, sysNavIvar);
if (!action) {
return NO;
}
NSUInteger destination = action.destinations.firstObject.unsignedIntegerValue;
return [action sendResponseForDestination:destination];
}
En particular, el método -sendResponseForDestination:
realiza la acción de "retroceso" real.
(Dado que la API no está documentada, Gboard está utilizando la API incorrectamente . Utilizaron la firma incorrecta -(void)sendResponseForDestination:(id)destination
. Pero sucede que todos los números que no sean 1
funcionarán igual, por lo que los desarrolladores de Google son suerte esta vez)