SIRIKIT
COCOAHEADS - MONTPELLIER – 17 NOVEMBRE 2016
AU SOMMAIRE…
• Quoi de neuf ?
• Traiter une demande
• Ajouter du vocabulaire
• Personnaliser l’affichage
• Démo
28.11.16 BACKELITE 2
QUOI DE NEUF ?
QUOI DE NEUF AVEC SIRIKIT ?
28.11.16 BACKELITE 4
• A partir d’iOS 10, Siri s’ouvre aux applications tierces
• Domaines disponibles :
 Réservation de véhicule
 Messages
 Photos
 Paiements
 Communication audio et vidéo
 Fitness
 Restaurants (avec Plans)
 Carplay
TRAITER UNE DEMANDE
PRE-REQUIS
28.11.16 BACKELITE 6
• Une application iOS existante
• Implémenter le code de l’application utilisé par Siri dans un framework
• Utiliser un conteneur partagé pour les ressources communes
• iOS 10 / Xcode 8
COMMENT CA MARCHE ?
28.11.16 BACKELITE 7
• Utilisation d’une Intents Extension
• Un « intent » correspond à une demande de l’utilisateur
INExtension
Intent handler B 1 - Resolve
« Envoi un message »
2 - Confirm
3 - Handle
Action
INIntentResponse
INIntent
Intent handler A
INTENTS ET DOMAINES
A chaque domaine sa liste d’intents :
• Messages
o INSendMessageIntent
o INSearchForMessagesIntent
o INSetMessagesAttributes
• Paiements
o INSendPaymentIntent
o INRequestPaymentIntent
etc …
CONFIGURATION DU PROJET
28.11.16 BACKELITE 9
• Info.plist de l’extension
• Autoriser l’application à utiliser Siri
• Capability Siri activée
• App id supportant SiriKit
• Info.plist de l’application
INEXTENSION
28.11.16 BACKELITE 10
• Point d’entrée de l’extension
• Appelle le bon intent handler
class IntentExtension: INExtension {
override func handler(for intent: INIntent) -> Any? {
if intent is INSendMessageIntent {
return MessagesIntentHandler()
} else if intent is INStartAudioCallIntent {
return AudioCallIntentHandler()
} else {
return nil
}
}
}
INTENT HANDLER - RESOLVE
28.11.16 BACKELITE 11
• Vérification des paramètres de l’intent
• Peut solliciter l’utilisateur pour des précisions
func resolveRecipients(forSendMessage intent: INSendMessageIntent, with completion: @escaping ([INPersonResolutionResult]) -> Void)
{
guard let recipients = intent.recipients else {
return
}
if recipients.count == 0 {
completion([INPersonResolutionResult.needsValue()])
} else {
completion([INPersonResolutionResult.success(with: recipients[0])])
}
}
INTENT HANDLER - CONFIRM
28.11.16 BACKELITE 12
• Validation finale de l’intent avant son traitement
• Sollicite l’utilisateur dans certains cas :
• Demandes irréversibles
• Transactions financières
func confirm(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
completion(INSendMessageIntentResponse(code: .ready, userActivity: nil))
}
INTENT HANDLER - HANDLE
28.11.16 BACKELITE 13
• Réalise la tâche associée à l’intent
• Renvoie une réponse
func handle(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) {
var success = false
if let recipients = intent.recipients {
success = ContactsManager.sharedManager.sendMessage(to: recipients)
}
completion(INSendMessageIntentResponse(code: success ? .success : .failure, userActivity: nil))
}
AJOUTER DU VOCABULAIRE
VOCABULAIRE SPECIFIQUE A UN UTILISATEUR
28.11.16 BACKELITE 15
• Restreint aux catégories suivantes :
 Noms de contacts
 Groupes de contact
 Tags de photo
 Noms d’albums photos
 Noms d’exercices (fitness)
 Profils de voiture (CarPlay)
DispatchQueue(label: "SiriVocabulary").async {
let contactNicknames:NSOrderedSet = ["JeanMi", "Zozor", "Blop", "Toto"]
INVocabulary.shared().setVocabularyStrings(contactNicknames, of: .contactName)
}
• Utilise l’API INVocabulary depuis l’application
VOCABULAIRE COMMUN A TOUS LES UTILISATEURS
28.11.16 BACKELITE 16
• Utilise le fichier AppIntentVocabulary.plist
• Restreint aux catégories suivantes :
 Options de réservation d’un véhicule
 Noms d’exercices (fitness)
APPINTENTVOCABULARY.PLIST
28.11.16 BACKELITE 17
PERSONNALISER L’AFFICHAGE
PRINCIPE
28.11.16 BACKELITE 19
• Enrichir l’interface lors des échanges avec l’utilisateur
• Utilisation d’une Intents UI Extension
• Restreint aux domaines suivants
 Messages
 Paiements
 Réservation de véhicule
 Fitness
CONFIGURATION DU PROJET
28.11.16 BACKELITE 20
• Info.plist de l’extension
• Ajout du storyboard et d’un unique ViewController associé
CONFIGURATION DU VIEW CONTROLLER
28.11.16 BACKELITE 21
• Implémentation du protocole INUIHostedViewControlling
func configure(with interaction: INInteraction!, context: INUIHostedViewContext, completion: ((CGSize) -> Void)!) {
...
if let completion = completion {
completion(self.extensionContext!.hostedViewMaximumAllowedSize)
}
}
• Implémentation du protocole INUIHostedViewSiriProviding pour masquer
la vue par défaut dans Siri
var displaysMessage: Bool {
return true
}
DEMO
julien.coudsi@backelite.com
www.backelite.com
CONTACTEZ-NOUS
COUDSI Julien
Développeur iOS
28.11.16 BACKELITE 23

Sirikit par Julien Coudsi

  • 1.
  • 2.
    AU SOMMAIRE… • Quoide neuf ? • Traiter une demande • Ajouter du vocabulaire • Personnaliser l’affichage • Démo 28.11.16 BACKELITE 2
  • 3.
  • 4.
    QUOI DE NEUFAVEC SIRIKIT ? 28.11.16 BACKELITE 4 • A partir d’iOS 10, Siri s’ouvre aux applications tierces • Domaines disponibles :  Réservation de véhicule  Messages  Photos  Paiements  Communication audio et vidéo  Fitness  Restaurants (avec Plans)  Carplay
  • 5.
  • 6.
    PRE-REQUIS 28.11.16 BACKELITE 6 •Une application iOS existante • Implémenter le code de l’application utilisé par Siri dans un framework • Utiliser un conteneur partagé pour les ressources communes • iOS 10 / Xcode 8
  • 7.
    COMMENT CA MARCHE? 28.11.16 BACKELITE 7 • Utilisation d’une Intents Extension • Un « intent » correspond à une demande de l’utilisateur INExtension Intent handler B 1 - Resolve « Envoi un message » 2 - Confirm 3 - Handle Action INIntentResponse INIntent Intent handler A
  • 8.
    INTENTS ET DOMAINES Achaque domaine sa liste d’intents : • Messages o INSendMessageIntent o INSearchForMessagesIntent o INSetMessagesAttributes • Paiements o INSendPaymentIntent o INRequestPaymentIntent etc …
  • 9.
    CONFIGURATION DU PROJET 28.11.16BACKELITE 9 • Info.plist de l’extension • Autoriser l’application à utiliser Siri • Capability Siri activée • App id supportant SiriKit • Info.plist de l’application
  • 10.
    INEXTENSION 28.11.16 BACKELITE 10 •Point d’entrée de l’extension • Appelle le bon intent handler class IntentExtension: INExtension { override func handler(for intent: INIntent) -> Any? { if intent is INSendMessageIntent { return MessagesIntentHandler() } else if intent is INStartAudioCallIntent { return AudioCallIntentHandler() } else { return nil } } }
  • 11.
    INTENT HANDLER -RESOLVE 28.11.16 BACKELITE 11 • Vérification des paramètres de l’intent • Peut solliciter l’utilisateur pour des précisions func resolveRecipients(forSendMessage intent: INSendMessageIntent, with completion: @escaping ([INPersonResolutionResult]) -> Void) { guard let recipients = intent.recipients else { return } if recipients.count == 0 { completion([INPersonResolutionResult.needsValue()]) } else { completion([INPersonResolutionResult.success(with: recipients[0])]) } }
  • 12.
    INTENT HANDLER -CONFIRM 28.11.16 BACKELITE 12 • Validation finale de l’intent avant son traitement • Sollicite l’utilisateur dans certains cas : • Demandes irréversibles • Transactions financières func confirm(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { completion(INSendMessageIntentResponse(code: .ready, userActivity: nil)) }
  • 13.
    INTENT HANDLER -HANDLE 28.11.16 BACKELITE 13 • Réalise la tâche associée à l’intent • Renvoie une réponse func handle(sendMessage intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { var success = false if let recipients = intent.recipients { success = ContactsManager.sharedManager.sendMessage(to: recipients) } completion(INSendMessageIntentResponse(code: success ? .success : .failure, userActivity: nil)) }
  • 14.
  • 15.
    VOCABULAIRE SPECIFIQUE AUN UTILISATEUR 28.11.16 BACKELITE 15 • Restreint aux catégories suivantes :  Noms de contacts  Groupes de contact  Tags de photo  Noms d’albums photos  Noms d’exercices (fitness)  Profils de voiture (CarPlay) DispatchQueue(label: "SiriVocabulary").async { let contactNicknames:NSOrderedSet = ["JeanMi", "Zozor", "Blop", "Toto"] INVocabulary.shared().setVocabularyStrings(contactNicknames, of: .contactName) } • Utilise l’API INVocabulary depuis l’application
  • 16.
    VOCABULAIRE COMMUN ATOUS LES UTILISATEURS 28.11.16 BACKELITE 16 • Utilise le fichier AppIntentVocabulary.plist • Restreint aux catégories suivantes :  Options de réservation d’un véhicule  Noms d’exercices (fitness)
  • 17.
  • 18.
  • 19.
    PRINCIPE 28.11.16 BACKELITE 19 •Enrichir l’interface lors des échanges avec l’utilisateur • Utilisation d’une Intents UI Extension • Restreint aux domaines suivants  Messages  Paiements  Réservation de véhicule  Fitness
  • 20.
    CONFIGURATION DU PROJET 28.11.16BACKELITE 20 • Info.plist de l’extension • Ajout du storyboard et d’un unique ViewController associé
  • 21.
    CONFIGURATION DU VIEWCONTROLLER 28.11.16 BACKELITE 21 • Implémentation du protocole INUIHostedViewControlling func configure(with interaction: INInteraction!, context: INUIHostedViewContext, completion: ((CGSize) -> Void)!) { ... if let completion = completion { completion(self.extensionContext!.hostedViewMaximumAllowedSize) } } • Implémentation du protocole INUIHostedViewSiriProviding pour masquer la vue par défaut dans Siri var displaysMessage: Bool { return true }
  • 22.
  • 23.

Notes de l'éditeur

  • #10 IntentsSupported : intents supportés IntentsRestrictedWhileLocked : intents supportés nécessitant que le device soit déverouillé S’il y a ambiguité, SiriKit utilise l’ordre des intents dans « IntentsSupported » , il faut mettre le plus pertinent en premier. Important notamment si l’extension supporte plusieurs domaines avec des sémantiques similaires (par exemple envoi de message et appel audio)
  • #12 Peut solliciter l’utilisateur pour des précisions Demander des précisions seulement si nécessaire, sinon c’est frustrant pour l’utilisateur
  • #13 Par exemple, si on a besoin d’Internet, vérification de la connectivité
  • #14 Ajout = lance l’animation Pour stopper : on enlève l’animation du layer
  • #16 Ajout = lance l’animation Pour stopper : on enlève l’animation du layer
  • #17 Ajout = lance l’animation Pour stopper : on enlève l’animation du layer
  • #18 Ajout = lance l’animation Pour stopper : on enlève l’animation du layer
  • #20 Ajout = lance l’animation Pour stopper : on enlève l’animation du layer
  • #21 Ajout = lance l’animation Pour stopper : on enlève l’animation du layer