Mit iOS 10 hat Apple die Funktionen von Siri für Drittanbieter-Apps erweitert. Jetzt können Sie Ihre eigenen Apps mithilfe von Sprachbefehlen erweitern und Ihren Nutzern Bots-ähnliche Interaktionen bieten.
Wir haben gerade eine iOS-App für einen unserer Kunden entwickelt, die mit Siri integriert ist. Die App ermöglicht es Kunden eines Beratungsunternehmens, über ein Sprachnachrichtensystem mit ihren Führungskräften zu kommunizieren. So funktioniert es: Ein Nutzer öffnet Siri und sagt: “Sende eine”. Eine Nachricht, in der meine Manager erfahren, dass ich Hilfe benötige.“ Dann wird der Antrag an die Manager gesendet.
In diesem Artikel erklären wir Ihnen, wie wir Siri in unsere App integriert haben. Wir hoffen, dass dieser Artikel eine nützliche Anleitung sein wird, die Ihnen hilft, eigene Apps mit Sprachassistenten zu entwickeln.
Die Auswahl der Domains
Bevor Sie beginnen, müssen Sie eine Domäne auswählen, die auf den Aufgaben basiert, die Ihre App ausführen soll. Wie in der SiriKit-Programmierungsgrundlagen, Es stehen Ihnen einige Domänen zur Auswahl: VoIP-Anrufe, Messaging, Zahlungen, Fotos, Trainings, Fahrpläne, CarPlay, Autokommandos, Restaurantreservierungen, Listen und Notizen, visuelle Codes (Unterstützung für QR-Codes) und Medien.
Wir haben den Bereich „Messaging“ für unsere Siri-Integration ausgewählt.
Siri nutzt Intents, um Benutzeraktionen zu verarbeiten. Wenn ein Benutzer eine Aktion von Siri anfordert, sendet es das Intentionen des Benutzers zusammen mit den notwendigen zusätzlichen Informationen an den Handler für diese Intention. Um diese Daten effektiv zu verarbeiten und zu verwalten, haben wir mit einem Partner zusammengearbeitet. Datenengineering-Unternehmen Um unsere Backend-Systeme zu optimieren und sicherzustellen, dass der Informationsfluss zwischen der App und dem Server reibungslos und effizient bleibt. Dieser Ansatz ähnelt den Strategien, die bei der Implementierung von Kreditfunktionen angewendet werden, wo robuste Backend-Systeme für reibungslose Finanzoperationen unerlässlich sind.
Das Messaging-Bereich von Siri unterstützt drei Arten von Intents: das Senden einer Nachricht, das Suchen nach einer Nachricht und die Zuordnung von Attributen zu einer Nachricht. Jedes dieser Intents verfügt über ein eigenes Protokoll, das von allen Handlern für diesen Intent implementiert werden muss.
SiriKit bietet außerdem die Möglichkeit, die Standard-Benutzeroberfläche im Siri-Fenster zu erweitern, aber in unserem Fall passt die Standard-Benutzeroberfläche völlig ausreichend.
Einrichten
Zuerst mussten wir für unsere App einen separaten Rahmenwerk erstellen. Da die Siri-Unterstützung über die Intents-Erweiterung implementiert werden muss, können Sie keinen Code direkt aus Ihrem Projekt verwenden. Deshalb haben wir das separate Framework verwendet.
Sie können das Framework so einrichten, indem Sie die Menüleiste von Xcode auswählen und “Datei–>Neu–>Ziel”. Anschließend wird Sie gefragt, welche Vorlage für Ihr Ziel verwendet werden soll. Wählen Sie “Framework”.”
Im nächsten Fenster können Sie die Vorlagenoptionen ändern und Ihrem Framework einen Namen zuweisen. Nenne es einfach ”Core”. Vergewissern Sie sich erneut, dass Ihr Framework den gleichen Projektnamen hat, und aktivieren Sie das Feld “In Anwendung einbetten”.
Die Einbindung von Klassen in das Framework
Danach müssen Sie dem Framework Klassen hinzufügen. In unserem Fall haben wir Klassen hinzugefügt, die das Anwendungsgebiet der Benutzeranforderungen definieren und diese Anfragen an unser Backend-Team senden.
Wenn Sie Ihre Klassen bereits implementiert haben, müssen Sie diese in den “Core” integrieren. Dies kann dadurch erreicht werden, dass Sie Ihre Klassen aus Ihrem Hauptziel entfernen und sie manuell in das Framework-Ziel hinzufügen. Anschließend können Sie in Ihrem Hauptziel das “Core”-Framework importieren und Ihre Klassen verwenden.
Implementierung des Intent-Handlers
Der wichtigste Teil der Integration von Siri in Ihre App besteht darin, den Intent-Handler zu implementieren. Dazu müssen Sie Ihrem Applikation die Zielvorrichtung “Intents Extension” hinzufügen, indem Sie “Datei – > Neu – > Ziel” auswählen und dann “Intents Extension” auswählen. Anschließend werden Sie gebeten, einen Namen einzugeben. Nenne ihn einfach “SiriIntentExtension”.”
Um dem System Informationen darüber zur Verfügung zu stellen, auf welche Intenten die App reagieren sollte, müssen wir einige Daten in die Datei “Info.plist” der “SiriIntentExtension” hinzufügen:
<key>NSExtensionNSExtensionAttributesIntensitäten unterstütztINSendMessageIntentNSExtensionPointIdentifiercom.apple.intents-serviceNSExtensionPrincipalClass$(PRODUCT_MODULE_NAME).IntentHandler
In dem obigen Code haben wir die unterstützte Intentenliste angegeben (in unserem Fall enthält sie nur eine Intent, nämlich “INSendMessageIntent”). Wenn Sie den Zugriff auf Intenten für gesperrte Geräte beschränken müssen, können Sie mithilfe der Schlüssel “IntentsRestrictedWhileLocked” eine beschränkte Intentenliste festlegen.
Die Schlüssel “NSExtensionPrincipalClass” enthält den Namen der Klasse in Ihrer IntentsExtension, die bestimmt, welcher Handler für einen bestimmten Intent verwendet werden soll. Wir haben beschlossen, diese Klasse “IntentHandler” zu nennen.”
Die Implementierung der Klasse IntentHandler ist ziemlich einfach:
Importieren Intensitäten
Klasse IntentHandler: INExtension {
Überlagern func Handler(für Intent: INIntent) -> Nichts? {
zurück MessagesIntentHandler()
}
}
Im obigen Code werden für jeden bestimmten Intent eine Instanz von “MessagesIntentHandler” zurückgegeben, da wir nur für einen einzigen Intent-Typ abonniert haben. Wenn Sie Unterstützung für verschiedene Intent-Typen implementieren möchten, können Sie überprüfen, für welchen Intent der Handler bereitgestellt werden soll:
wenn Absicht ist INSendMessageIntent {
zurück MessagesIntentHandler()
}
Wie Sie vielleicht schon erraten haben, ist “MessagesIntentHandler” die Klasse, in der alles abläuft. Hier ist die Implementierung dieser Klasse:
Klasse MessagesIntentHandler: NSObject, INSendMessageIntentHandling {
...
}
Das Protokoll “INSendMessageIntentHandling” erfordert die Verwendung des “NSObjectProtocol”, weshalb der Handler von “NSObject” abgeleitet wird. Das Protokoll “INSendMessageIntentHandling” enthält eine erforderliche und vier optionale Funktionen. Sie finden weitere Informationen dazu. hier. Momentan sind wir nur an den vier optionalen Funktionen interessiert.
Die erste Funktion, die optionale, lautet “resolveRecipients(forSendMessage:with:).” In dieser Funktion können Sie die Empfänger für einen bestimmten Intent angeben.
Da der Empfänger in unserem Fall eine einzige Einheit ist (der Server), akzeptieren wir einfach alle vorgeschlagenen Empfänger, damit Siri den Nutzern nicht auffordert, den Empfänger selbst zu bestimmen:
func resolveRecipients(für intentSendMessage: INSendMessageIntent, mit der Kompletion-Methode @escaping) ([INPersonResolutionResult]) -> Nichtig) {
Wächter lassen Empfänger = intent.recipients else {
Abschluss([])
zurück
}
lassen ResolutionResults = recipients.Karte { INPersonResolutionResult.success(mit: $0) }
Ergebnis der Abwicklung (resolutionResults)
}
In dem obigen Code werden die möglichen Empfänger aus dem Intent abgeleitet und für jeden davon ein Resolution-Ergebnis bereitgestellt.
Die nächste Funktion lautet “resolveContent(forSendMessage:with:).” Diese Funktion ermöglicht es Ihnen, den eingegebenen Text zu überprüfen. In unserer Anwendung filtern wir einfach leere Anfragen aus:
func resolveContent(für intentSendMessage: INSendMessageIntent, mit der Kompletion-Methode @escaping) (INStringResolutionResult) -> Nichtig) {
wenn lassen text = intent.content, !text.isEmpty {
completion(INStringResolutionResult.success(with: text))
} else {
Fertigstellung(INStringResolutionResult.needsValue())
}
}
Die Benutzer müssen sich autorisieren, bevor sie unsere App nutzen können, und daher sollten nur autorisierte Benutzer auf die Funktionen von SiriIntentExtension zugreifen können. Um sicherzustellen, dass nur autorisierte Benutzer Zugriff haben, benötigen wir das Protokoll “INSendMessageIntentHandling”, das die Funktion “confirm(sendMessage:completion:)” enthält:
func Bestätigen(sendMessage intent: INSendMessageIntent, completion: @escaping) (INSendMessageIntentResponse) -> Nichtig) {
lassen userActivity = NSUserActivity(activityType: String(Beschreibung: INSendMessageIntent.selbst))
lassen responseCode: INSendMessageIntentResponseCode
wenn !NetworkReachability.isReachable {
userActivity.userInfo = ["Fehler": SiriIntentError.noInternetConnection]
responseCode = .FailureMessageServiceNotAvailable
} else wenn !UserSession.hasAuthorizedSession() {
userActivity.userInfo = ["Fehler": SiriIntentError.notAuthorized]
responseCode = .failureRequiringAppLaunch
} else {
responseCode = .success
}
lassen Antwort = INSendMessageIntentResponse(Code: responseCode, Benutzeraktivität: userActivity)
Abschluss (Antwort)
}
In dem obigen Code prüfen wir, ob eine Internetverbindung verfügbar ist und ob ein Benutzer in der Anwendung angemeldet ist. “NSUserActivity” wird der Anwendung übergeben, wenn die App geöffnet wird. Wenn die Validierung fehlschlägt, geben wir eine Fehlermeldung und einen entsprechenden Statuscode zurück. Beispiel: Wenn wir “failureRequiringAppLaunch” übergeben, schlägt Siri vor, dass ein Benutzer eine App öffnet. Wenn der Benutzer die App öffnet, könnten wir die “userActivity” löschen und den Benutzer bitten, nach der Autorisierung erneut zu versuchen.
Nun zur letzten und wichtigsten Funktion:
func Bestätigen(sendMessage intent: INSendMessageIntent, completion: @escaping) (INSendMessageIntentResponse) -> Nichtig) {
lassen userActivity = NSUserActivity(activityType: String(Beschreibung: INSendMessageIntent.selbst))
lassen responseCode: INSendMessageIntentResponseCode
wenn !NetworkReachability.isReachable {
userActivity.userInfo = ["Fehler": SiriIntentError.noInternetConnection]
responseCode = .FailureMessageServiceNotAvailable
} else wenn !UserSession.hasAuthorizedSession() {
userActivity.userInfo = ["Fehler": SiriIntentError.notAuthorized]
responseCode = .failureRequiringAppLaunch
} else {
responseCode = .success
}
lassen Antwort = INSendMessageIntentResponse(Code: responseCode, Benutzeraktivität: userActivity)
Abschluss (Antwort)
}
In dieser Funktion löschen wir den Domänenbereich einer Benutzeranforderung und senden eine verpackte Nachricht an den Server. “intent.content” enthält eine Textnachricht, die vom Benutzer aufgezeichnet wurde. Falls unser Versuch fehlschlägt, senden wir einen Antwortcode “”. failure“, damit Siri dem Benutzer mitteilen kann, dass seine Anfrage nicht gesendet wurde.
Denken Sie daran, dass Sie den Schlüssel “NSSiriUsageDescription” in die “Info.plist” Ihrer App hinzufügen müssen.”
Prüfung
Lasst uns es testen!
Wir gehen davon aus, dass meine App die Bezeichnung “Awesome” trägt und meine “NSSiriUsageDescription” den Text “Zum Beispiel” enthält.”
Versuchen Sie Siri anzuzeigen und sagen Sie: “Sende Awesome eine Nachricht mit dem Text ”Testnachricht‘.“ Dies führt zu dem nächsten Bildschirm:
Beachten Sie, dass Sie diesen Bildschirm nicht sehen werden, wenn Sie Siri manuell für eine bestimmte Person anfordern. Okay, wählen wir “Ja”. Nun sehen wir den folgenden Bildschirm:
Dies ist der Bereich, den Sie mit Ihrem eigenen Design anpassen können. Wenn Sie versuchen, auf diese Funktionalität zuzugreifen, ohne eine Internetverbindung, wird der erste Fall in unserer Validierung ausgelöst und Sie sehen den folgenden Bildschirm:
Fazit
Zum Abschluss möchten wir einige Dinge erwähnen, die man bei der Entwicklung einer Erweiterung wie der unseren im Hinterkopf behalten sollte:
- Wenn Sie Netzwerkanfragen verwenden, müssen Sie sowohl für die App als auch für die SiriIntentExtension Ihre Domäne in die Ausnahmen für “App Transport Security Settings” hinzufügen.”
- Wie in den Dokumenten von Apple beschrieben, können Sie ein eigenes benutzerdefiniertes Wörterbuch mit app-spezifischen und benutzerdefinierten Wörtern implementieren, das Siri möglicherweise missverstehen könnte. Es ist optional, aber Sie werden dies während des Apple-Review-Prozesses daran erinnert.
- Sie können die Berechtigung “Siri-Verwendung” manuell beantragen, indem Sie „INPreferences.requestSiriAuthorization“ anrufen. Wenn Sie dies jedoch nicht tun, wird Siri bei der ersten Nutzung darum bitten, dies zu tun.
- Siri erkennt Ihre App nur anhand ihres Namens. Wenn Sie beispielsweise für Ihre App englische und russische Lokalisierungen bereitstellen, ohne eine Lokalisierung des Namens anzugeben, erkennt Siri Ihre App nicht, wenn ein Benutzer Russisch als seine Siri-Sprache festlegt. Um dieses Problem zu lösen, können Sie für jede Lokalisierung einen Schlüssel “CFBundleDisplayName” bereitstellen, der den entsprechenden Wert enthält.