49 votes

Comment le clavier iOS personnalisé de Google, Gboard, supprime-t-il par programme l'application la plus en vue?

Google custom iOS, Gboard, a une fonctionnalité intéressante qui ne peut être accompli en utilisant des Api publiques dans le SDK iOS (comme d'iOS 10). Je voudrais savoir exactement comment Google accomplit la tâche de par programme sautant en arrière d'une application dans l'app Commutation pile dans Gboard.

Custom iOS claviers ont deux composantes principales: le conteneur d'application et le clavier de l'application de l'extension. Le clavier de l'application de l'extension fonctionne dans un système d'exploitation distinct processus qui est lancé à chaque fois qu'un utilisateur est dans n'importe quelle application sur leur téléphone qui nécessite la saisie de texte.

Ce sont approximatives étapes qui peuvent être suivies, à l'aide de Gboard, pour voir l'effet de par programmation, un retour à une application précédente:

  1. Un utilisateur démarre le Apple des Messages de l' application sur leur iPhone et tape un champ de texte pour commencer la saisie du texte.
  2. Le Gboard d'extension du clavier est lancé et les utilisateurs voit le Gboard clavier personnalisé (alors qu'ils sont encore dans l'Apple app Messages).
  3. L'utilisateur appuie sur la touche microphone à l'intérieur de la Gboard d'extension du clavier pour faire de la voix de saisie de texte.
  4. Gboard utilise une url personnalisée régime pour le lancement de la Gboard app container. Le Gboard clavier et Apple app messages sont poussés vers le bas d'une couche dans l'Application de la pile et de la Gboard app container est maintenant la première application dans l'app pile. Le Gboard conteneur application utilise le microphone pour écouter l'utilisateur de la parole et les traduit en texte lesquels il place sur l'écran.
  5. L'utilisateur appuie sur le bouton "Terminé" quand ils sont satisfaits de la saisie de texte qu'ils voient sur l'écran.
  6. C'est là que la magie opère... comme l'écran de saisie de texte est rejeté, la Gboard app container est également rejetée automatiquement. Le Gboard app container s'en va et est remplacé par l'Apple app Messages (parfois de la Gboard clavier processus d'extension est encore en vie, parfois, il est relancé, et parfois, il a besoin d'être relancé manuellement en appuyant sur à l'intérieur d'un champ de texte.) . Comment est-ce que Google accomplir cette mission?
  7. Enfin, l'utilisateur voit le texte qui vient d'être traduit automatiquement insérée à l'intérieur du champ de saisie de texte. Sans doute Google accomplit cette mission par le partage de données entre les Gboard app container et l'extension du clavier.

Je suppose que Google est en utilisant des Api privées en explorant la barre d'état de la vue de la hiérarchie en Objective-C runtime introspection et en quelque sorte de synthèse appuyez sur événements ou d'appeler un exposé objectif / action. J'ai exploré un peu et ont été en mesure de trouver d'intéressant UIView sous-classes à l'intérieur de la barre d'état, comme UIStatusBarBreadcrumbItemView qui contient un tableau de UISystemNavigationActions. Je continue à explorer ces classes dans l'espoir que je puisse trouver un moyen de reproduire l'interaction de l'utilisateur.

Je comprends que l'utilisation d'Api privées est une bonne façon d'obtenir votre application à été rejeté à partir de l'App Store - ce n'est pas une préoccupation que j'aimerais être abordés dans la réponse. Je suis à la recherche principalement pour des réponses précises sur la façon exactement comment Google accomplit la tâche de par programme sautant en arrière d'une application dans l'app Commutation pile dans Gboard.

55voto

KennyTM Points 232647

Votre supposition est correcte - Gboard est l'utilisation privée de l'API pour le faire.

... mais pas par le biais de l'exploration de vue de la hiérarchie ou de l'événement injection.

Lorsque la voix-texte d'action est fait, nous pouvons vérifier le syslog de Xcode, ou de la Console qu'il appelle l' -[AVAudioSession setActive:withOptions:error:] méthode. J'ai donc démonté le Gboard application et de rechercher la trace de la pile en la matière.

L'escalade jusqu'à la pile d'appel, nous pouvons trouver l' -[GKBVoiceRecognitionViewController navigateBackToPreviousApp] méthode, et...

enter image description here

..._systemNavigationAction? Oui, définitivement privé de l'API.

Depuis class_getInstanceVariable est une API publique et de l' "_systemNavigationAction" est un littéral de chaîne, le correcteur automatique n'est pas en mesure de noter le privé, l'utilisation de l'API, et les examinateurs de l'homme n'est probablement pas voir quelque chose de mal avec le "saut à l'application précédente" de comportement. Ou, probablement parce qu'ils sont Google et vous n'êtes pas...


Le code qui effectue le "saut à l'application précédente" l'action est comme ceci:

@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 particulier, l' -sendResponseForDestination: méthode effectue le "retour" de l'action.

(Depuis l'API est sans-papiers, Gboard est fait à l'aide de l'API de manière incorrecte. Ils ont utilisé la signature incorrecte -(void)sendResponseForDestination:(id)destination. Mais il arrive que tous les autres nombres de 1 fonctionnera de la même, de sorte que le les développeurs de Google ont de la chance cette fois)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X