iOS 9 : comment utiliser la nouvelle API de recherche

Par Benjamin Lavialle, le 22.07.2015

Depuis iOS 8, Apple propose Handoff, une technologie qui permet à un utilisateur de commencer une activité sur son Mac et de la finir sur son iPhone et vice versa. Pour plus de détails, nous vous invitons à lire notre article sur Handoff sur notre blog. Il y a quelques mois, lors de la sortie de l’Apple Watch, Handoff est devenu le moyen de commencer une activité sur la montre et de la continuer sur son téléphone.

Avec iOS 9, Apple propose de reprendre le principe de Handoff en l’associant avec Spotlight. Il est en effet maintenant possible de rechercher, dans Spotlight, des activités réalisées, du contenu d’application, et même des activités populaires auprès d’autres utilisateurs, sans avoir l’application installée sur l’appareil.

Pour cela, il suffit à l’application de déclarer les activités qu’elle lance (grâce à NSUserActivity), ainsi que le contenu qu’elle peut présenter (grâce à Core Spotlight) ; le système se charge ensuite d’indexer ces informations, de façon locale ou distante.

NSUserActivity : retrouver une activité

De la même façon dont on utilise NSUserActivity pour créer une passerelle entre les appareils et continuer une activité avec Handoff, il est maintenant possible d’ajouter des informations complémentaires permettant le référencement, la recherche puis la reprise d’une activité. Pour cela il suffit d’ajouter quelques renseignements sur l’activité courante lors de sa création :

NSUserActivity * userActivity = [[NSUserActivity alloc] initWithActivityType:@"com.applidium.test-activity"];
userActivity.title = title;
userActivity.keywords = keywords;
userActivity.userInfo = userInfo;
userActivity.eligibleForSearch = YES;
userActivity.eligibleForPublicIndexing = YES;
userActivity.eligibleForHandoff = YES;
userActivity.contentAttributeSet = attributeSet;
[userActivity becomeCurrent];

keywords définit l’ensemble des mots clés utilisés pour la recherche ; userInfo contient les informations nécessaires à la reconstruction de l’activité (de la même facon que Handoff) ; les différents champs eligibleFor(…) définissent les domaines d’utilisation de l’activité pour le système : avec Handoff, avec la recherche, avec la recherche pour tous les utilisateurs.

Il faut noter qu’Apple précise qu’il ne faut pas abuser des mots clés, et nous met en garde : les mots clés non pertinents sont détectés et l’activité ne pourra pas être trouvée par leur biais.

Les activités peuvent devenir publiques, c’est à dire recherchables par d’autres utilisateurs, potentiellement n’ayant pas l’application installée. Pour cela, iOS gère deux index d’activité, un local, par appareil, et un distant, commun à tout le monde. Lorsqu’une activité est déclarée publique, iOS envoie le hash de celle-ci au serveur d’indexage ; lorsque plusieurs appareils ont envoyé le même hash, le serveur l’indexe pour les autres utilisateurs. Ce mécanisme permet de garantir que l’activité ne contient pas les données personnelles d’un utilisateur, mais est bien générique. Lorsqu’un utilisateur sélectionne une activité d’application qu’il n’a pas, Spotlight lui présente une page de l’AppStore lui proposant de la télécharger.

Pour répondre à un résultat de recherche, il faut (de la même manière que pour Handoff) implémenter la méthode de l’appDelegate :

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler

C’est dans cette méthode qu’il faut recréer la vue associée à l’activité pour la présenter à l’utilisateur.

Core Spotlight : rendre du contenu recherchable

Il est aussi possible d’indexer du contenu d’application, de manière locale, pour Spotlight ; pour cela, il faut utiliser Core Spotlight.

Core Spotlight se charge de garder un index local entre identifiant de contenu et mot clé ; charge au développeur d’ajouter du contenu par clé :

CSSearchableItemAttributeSet * attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString*)kUTTypeJSON];
  attributeSet.title = content.title;
  attributeSet.contentDescription = content.contentDescription;
  CSSearchableItem * item = [[CSSearchableItem alloc] initWithUniqueIdentifier:content.uniqueID domainIdentifier:domainID attributeSet:attributeSet];
  [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:@[item] completionHandler: ^(NSError * __nullable error) {
    NSLog(@"Search item indexed");
}];

Le contentType de CSSearchableItemAttributeSet vient de UTCoreTypes dans MobileCoreServices. En plus de l’identifier de l’item, il est possible d’ajouter un domaine ; celui-ci permettra ensuite, par exemple, de supprimer l’ensemble des index d’un domaine. CSSearchableIndex permet la gestion du contenu indexé par application ; il permet d’ajouter du contenu, de modifier les entrées, ou de les supprimer.

Une fois que l’élément est ajouté à l’index, il est recherchable dans Spotlight ; une fois sélectionné par l’utilisateur, le système appelle la méthode de l’appDelegate :

- (BOOL)application:(nonnull UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray * __nullable))restorationHandler

On sait que l’activité correspond à une recherche de contenu indexé lorsque :

[userActivity.activityType isEqualToString:CSSearchableItemActionType]

Il faut ensuite retrouver le contenu grâce à son identifiant accessible avec :

[userActivity.userInfo objectForKey:CSSearchableItemActivityIdentifier]

Ensuite on doit recréer la vue d’affichage de l’élément. L’idée étant d’amener l’utilisateur à l’écran qu’il aurait eu s’il avait voulu accéder à l’élément directement dans l’application.

Conclusion

Avec iOS 9, Apple a voulu mettre Spotlight au coeur de l’utilisation d’iOS ; ces nouvelles méthodes d’indexation offrent aux applications un nouveau moyen de s’intégrer plus profondément dans le système. L’utilisation conjointe de ces deux nouvelles API donne, au développeur, la possibilité d’augmenter la visibilité de son application avec de nouveaux points d’entrée directement au coeur de l’application ; cela apporte un réel plus à l’expérience utilisateur, qu’il semble judicieux d’exploiter.