ความตั้งใจของ SiriKit จะเข้ากับแอปของคุณหรือไม่? ถ้าใช่ นี่คือวิธีใช้งาน

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ ตั้งแต่ปีที่แล้ว คุณสามารถเพิ่มการรองรับ Siri ให้กับแอพได้ หากแอปนั้นเหมาะสมกับกรณีการใช้งานที่กำหนดไว้ล่วงหน้าของ Apple ค้นหาว่า SiriKit จะใช้ได้ผลสำหรับคุณหรือไม่และจะใช้งานอย่างไร

ตั้งแต่ iOS 5 Siri ได้ช่วยให้ผู้ใช้ iPhone ส่งข้อความ ตั้งระบบเตือนความจำ และค้นหาร้านอาหารด้วยแอพของ Apple เริ่มต้นใน iOS 10 เราสามารถใช้ Siri ในแอปบางตัวของเราได้เช่นกัน

เพื่อใช้ฟังก์ชันนี้ แอปของคุณต้องพอดีกับ "โดเมนและความตั้งใจ" ที่กำหนดไว้ล่วงหน้าของ Siri ของ Apple ในบทความนี้ เราจะเรียนรู้เกี่ยวกับสิ่งเหล่านั้นและดูว่าแอพของเราสามารถใช้งานได้หรือไม่ เราจะนำแอพง่าย ๆ ที่เป็นตัวจัดการรายการสิ่งที่ต้องทำและเรียนรู้วิธีเพิ่มการรองรับ Siri เราจะอ่านหลักเกณฑ์ของเว็บไซต์นักพัฒนา Apple เกี่ยวกับการกำหนดค่าและรหัส Swift สำหรับส่วนขยายประเภทใหม่ที่นำมาใช้กับ SiriKit: ส่วนขยาย Intents

เมื่อคุณมาถึงส่วนการเขียนโค้ดของบทความนี้ คุณจะต้องใช้ Xcode (อย่างน้อยเวอร์ชัน 9.x) และคงจะดีถ้าคุณคุ้นเคยกับการพัฒนา iOS ใน Swift เพราะเราจะเพิ่ม Siri ให้กับงานเล็กๆ แอป. เราจะดำเนินการตามขั้นตอนในการตั้งค่าส่วนขยายในเว็บไซต์นักพัฒนาซอฟต์แวร์ของ Apple และในการเพิ่มรหัสส่วนขยายของ Siri ลงในแอป

“ เฮ้ Siri ทำไมฉันต้องการคุณ”

บางครั้งฉันใช้โทรศัพท์ขณะอยู่บนโซฟาโดยที่ไม่ต้องใช้มือทั้งสองข้าง และสามารถให้ความสนใจกับหน้าจอได้เต็มที่ บางทีฉันจะส่งข้อความหาพี่สาวเพื่อวางแผนวันเกิดแม่ของเรา หรือตอบคำถามใน Trello ฉันสามารถเห็นแอพ ฉันสามารถแตะที่หน้าจอ ฉันสามารถพิมพ์

แต่ฉันอาจจะเดินไปรอบ ๆ เมืองของฉัน ฟังพอดแคสต์ เมื่อมีข้อความเข้ามาในนาฬิกา โทรศัพท์ของฉันอยู่ในกระเป๋าเสื้อ และฉันไม่สามารถรับสายได้ง่ายในขณะเดิน

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

เมื่อใช้ Siri ฉันสามารถกดปุ่มควบคุมของหูฟังค้างไว้แล้วพูดว่า “ส่งข้อความหาน้องสาวของฉันว่าฉันจะไปที่นั่นตอนบ่ายสองโมง” Siri นั้นยอดเยี่ยมเมื่อคุณกำลังเดินทางและไม่สามารถให้ความสนใจกับโทรศัพท์ของคุณได้อย่างเต็มที่หรือเมื่อการโต้ตอบมีน้อย แต่ต้องใช้การแตะหลายครั้งและการพิมพ์จำนวนมาก

นี่เป็นเรื่องปกติถ้าฉันต้องการใช้แอพของ Apple สำหรับการโต้ตอบเหล่านี้ แต่แอพบางหมวดหมู่ เช่น การส่งข้อความ มีทางเลือกอื่นที่ได้รับความนิยมอย่างมาก กิจกรรมอื่นๆ เช่น การจองรถหรือจองโต๊ะในร้านอาหาร อาจไม่สามารถทำได้ด้วยแอปที่มาพร้อมเครื่องของ Apple แต่เหมาะสำหรับ Siri

แนวทางของ Apple สำหรับผู้ช่วยเสียง

ในการเปิดใช้งาน Siri ในแอปของบริษัทอื่น Apple ต้องตัดสินใจเกี่ยวกับกลไกในการรับเสียงจากเสียงของผู้ใช้และนำมันไปยังแอปในลักษณะที่สามารถตอบสนองคำขอได้ เพื่อให้เป็นไปได้ Apple กำหนดให้ผู้ใช้ระบุชื่อแอปในคำขอ แต่มีตัวเลือกหลายอย่างว่าจะทำอย่างไรกับคำขอที่เหลือ

  • มันสามารถส่งไฟล์เสียงไปยังแอพได้
    ประโยชน์ของแนวทางนี้คือ แอปสามารถพยายามจัดการกับคำขอใดๆ ที่ผู้ใช้อาจมีได้อย่างแท้จริง Amazon หรือ Google อาจชอบวิธีนี้เพราะมีบริการจดจำเสียงที่ซับซ้อนอยู่แล้ว แต่แอพส่วนใหญ่จะไม่สามารถจัดการสิ่งนี้ได้อย่างง่ายดาย
  • มันสามารถเปลี่ยนคำพูดเป็นข้อความและส่งสิ่งนั้นได้
    เนื่องจากแอปจำนวนมากไม่มีการใช้งานภาษาธรรมชาติที่ซับซ้อน ผู้ใช้จึงมักจะต้องยึดติดกับวลีที่เฉพาะเจาะจงมาก และการสนับสนุนที่ไม่ใช่ภาษาอังกฤษจะขึ้นอยู่กับนักพัฒนาแอปที่จะนำไปใช้
  • อาจขอให้คุณระบุรายการวลีที่คุณเข้าใจ
    กลไกนี้ใกล้เคียงกับสิ่งที่ Amazon ทำกับ Alexa (ในกรอบ "ทักษะ") และช่วยให้ใช้งาน Alexa ได้มากกว่าที่ SiriKit จัดการได้ในปัจจุบัน ในทักษะของ Alexa คุณจัดเตรียมวลีที่มีตัวแปรตัวยึดตำแหน่งที่ Alexa จะกรอกให้คุณ ตัวอย่างเช่น “Alexa เตือนฉันเมื่อ $TIME$ ถึง $REMINDER$ ” — Alexa จะใช้วลีนี้กับสิ่งที่ผู้ใช้พูดและบอกค่าของ TIME และ REMINDER เช่นเดียวกับกลไกก่อนหน้านี้ นักพัฒนาจำเป็นต้องทำการแปลทั้งหมด และไม่มีความยืดหยุ่นมากนักหากผู้ใช้พูดอะไรที่แตกต่างออกไปเล็กน้อย
  • สามารถกำหนดรายการคำขอด้วยพารามิเตอร์และส่งคำขอที่มีโครงสร้างให้แอป
    นี่คือสิ่งที่ Apple ทำจริง ๆ และข้อดีก็คือสามารถรองรับภาษาต่างๆ ได้ และพยายามทำความเข้าใจทุกวิถีทางที่ผู้ใช้จะพูดคำร้อง ข้อเสียใหญ่คือคุณสามารถใช้ตัวจัดการสำหรับคำขอที่ Apple กำหนดเท่านั้น สิ่งนี้ดีมากถ้าคุณมี ตัวอย่างเช่น แอพส่งข้อความ แต่หากคุณมีบริการสตรีมเพลงหรือเครื่องเล่นพอดคาสต์ คุณจะไม่มีทางใช้ SiriKit ได้เลย

ในทำนองเดียวกัน มีสามวิธีสำหรับแอปที่จะพูดคุยกับผู้ใช้: ด้วยเสียง กับข้อความที่แปลง หรือโดยการแสดงประเภทที่คุณต้องการพูดและปล่อยให้ระบบหาวิธีที่แน่นอนในการแสดงออก วิธีแก้ปัญหาสุดท้าย (ซึ่งเป็นสิ่งที่ Apple ทำ) ทำให้ Apple แบกรับภาระในการแปล แต่มีวิธีจำกัดในการใช้คำพูดของคุณเองเพื่ออธิบายสิ่งต่างๆ

ประเภทของคำขอที่คุณสามารถจัดการได้ถูกกำหนดไว้ในโดเมนและเจตนาของ SiriKit เจตนาคือคำขอประเภทหนึ่งที่ผู้ใช้อาจทำ เช่น ส่งข้อความถึงผู้ติดต่อหรือค้นหารูปภาพ ความตั้งใจแต่ละรายการมีรายการพารามิเตอร์ ตัวอย่างเช่น การส่งข้อความต้องมีผู้ติดต่อและข้อความ

โดเมนเป็นเพียงกลุ่มของความตั้งใจที่เกี่ยวข้อง การอ่านข้อความและการส่งข้อความอยู่ในโดเมนข้อความ การจองรถและรับตำแหน่งอยู่ในโดเมนการจองรถ มีโดเมนสำหรับการโทร VoIP เริ่มออกกำลังกาย ค้นหารูปภาพ และอีกสองสามอย่าง เอกสารประกอบของ SiriKit ประกอบด้วยรายการโดเมนทั้งหมดและจุดประสงค์

คำวิจารณ์ทั่วไปของ Siri คือ ดูเหมือนว่าไม่สามารถจัดการคำขอเช่นเดียวกับ Google และ Alexa และระบบนิเวศเสียงของบุคคลที่สามที่เปิดใช้งานโดยคู่แข่งของ Apple นั้นสมบูรณ์ยิ่งขึ้น

ฉันเห็นด้วยกับการวิพากษ์วิจารณ์เหล่านั้น หากแอพของคุณไม่เข้ากับจุดประสงค์ปัจจุบัน คุณจะใช้ SiriKit ไม่ได้ และคุณทำอะไรไม่ได้ แม้ว่าแอพของคุณจะพอดี คุณไม่สามารถควบคุมทุกคำที่ Siri พูดหรือเข้าใจได้ ดังนั้น หากคุณมีวิธีพูดเกี่ยวกับสิ่งต่างๆ ในแอปของคุณโดยเฉพาะ คุณจะไม่สามารถสอน Siri ได้เสมอไป

ความหวังของนักพัฒนา iOS คือทั้ง Apple จะขยายรายการความตั้งใจอย่างมากและการประมวลผลภาษาธรรมชาติจะดีขึ้นมาก หากเป็นเช่นนั้น เราจะมีผู้ช่วยเสียงที่ทำงานโดยที่นักพัฒนาซอฟต์แวร์ไม่ต้องแปลหรือเข้าใจวิธีการพูดแบบเดียวกันทั้งหมด และการนำการสนับสนุนสำหรับคำขอที่มีโครงสร้างไปใช้นั้นทำได้ค่อนข้างง่าย — ง่ายกว่าการสร้างโปรแกรมแยกวิเคราะห์ภาษาธรรมชาติมาก

ประโยชน์ที่สำคัญอีกประการของกรอบความตั้งใจคือไม่จำกัดเพียงคำขอของ Siri และคำสั่งเสียง แม้กระทั่งตอนนี้ แอป Maps ก็สร้างคำขอตามความตั้งใจของแอปได้ (เช่น การจองร้านอาหาร) มันทำสิ่งนี้โดยทางโปรแกรม (ไม่ใช่จากเสียงหรือภาษาธรรมชาติ) หาก Apple อนุญาตให้แอปค้นพบเจตนาที่เปิดเผยของกันและกัน เราจะมีวิธีการทำงานร่วมกันที่ดีกว่ามาก (ตรงข้ามกับ URL สไตล์ x-callback)

สุดท้าย เนื่องจาก Intent เป็นคำขอที่มีโครงสร้างซึ่งมีพารามิเตอร์ จึงมีวิธีง่ายๆ ที่แอปจะแสดงว่าพารามิเตอร์ขาดหายไปหรือต้องการความช่วยเหลือในการแยกแยะระหว่างตัวเลือกบางตัว จากนั้น Siri สามารถถามคำถามติดตามผลเพื่อแก้ไขพารามิเตอร์โดยที่แอปไม่จำเป็นต้องดำเนินการสนทนา

โดเมนการจองรถ

เพื่อทำความเข้าใจโดเมนและเจตนา ให้ดูโดเมนการจองรถ นี่คือโดเมนที่คุณจะใช้ขอให้ Siri ซื้อรถ Lyft ให้คุณ

Apple กำหนดวิธีการเรียกรถและวิธีรับข้อมูล แต่จริงๆ แล้วไม่มีแอป Apple ในตัวที่สามารถจัดการกับคำขอนี้ได้ นี่เป็นหนึ่งในไม่กี่โดเมนที่ต้องใช้แอปที่เปิดใช้งาน SiriKit

คุณสามารถเรียกใช้ความตั้งใจอย่างใดอย่างหนึ่งผ่านเสียงหรือโดยตรงจากแผนที่ จุดประสงค์บางประการสำหรับโดเมนนี้คือ:

  • เรียกรถ
    ใช้อันนี้เพื่อจองรถ คุณจะต้องระบุสถานที่รับและส่ง และแอปอาจจำเป็นต้องทราบขนาดของปาร์ตี้และประเภทของรถที่คุณต้องการ วลีตัวอย่างอาจเป็น "จองรถให้ฉันด้วย <appname>"
  • รับสถานะการเดินทาง
    ใช้ความตั้งใจนี้เพื่อค้นหาว่าได้รับคำขอของคุณแล้วหรือไม่ และเพื่อรับข้อมูลเกี่ยวกับรถและคนขับ รวมถึงตำแหน่งของพวกเขา แอป Maps ใช้ความตั้งใจนี้เพื่อแสดงภาพที่อัปเดตของรถขณะที่กำลังเข้าใกล้คุณ
  • ยกเลิกการเดินทาง
    ใช้สิ่งนี้เพื่อยกเลิกการโดยสารที่คุณจองไว้

สำหรับความตั้งใจนี้ Siri อาจจำเป็นต้องทราบข้อมูลเพิ่มเติม ดังที่คุณเห็นเมื่อเรานำ Intent Handler ไปใช้ ส่วนขยาย Intent ของคุณสามารถบอก Siri ได้ว่าไม่มีพารามิเตอร์ที่จำเป็น และ Siri จะแจ้งผู้ใช้ให้ทราบ

ความจริงที่ว่า Maps สามารถเรียกใช้ Intent แบบเป็นโปรแกรมได้แสดงให้เห็นว่า Intents อาจเปิดใช้การสื่อสารระหว่างแอปได้อย่างไรในอนาคต

หมายเหตุ : คุณสามารถรับรายการโดเมนทั้งหมดและจุดประสงค์ได้จากเว็บไซต์นักพัฒนาของ Apple นอกจากนี้ยังมีตัวอย่างแอพ Apple ที่มีการใช้งานโดเมนและความตั้งใจมากมาย รวมถึงการจองรถด้วย

การเพิ่มรายการและการสนับสนุนโดเมนโน้ตให้กับแอปของคุณ

ตกลง ตอนนี้เราเข้าใจพื้นฐานของ SiriKit แล้ว มาดูกันว่าคุณจะเพิ่มการรองรับ Siri ในแอปที่มีการกำหนดค่าจำนวนมากและคลาสสำหรับแต่ละจุดประสงค์ที่คุณต้องการจัดการได้อย่างไร

ส่วนที่เหลือของบทความนี้ประกอบด้วยขั้นตอนโดยละเอียดในการเพิ่มการรองรับ Siri ให้กับแอพ มีห้าสิ่งที่คุณต้องทำในระดับสูง:

  1. เตรียมเพิ่มส่วนขยายใหม่ให้กับแอปโดยสร้างโปรไฟล์การจัดเตรียมโดยให้สิทธิ์ใหม่บนเว็บไซต์นักพัฒนาของ Apple
  2. กำหนดค่าแอปของคุณ (ผ่าน plist ) เพื่อใช้การให้สิทธิ์
  3. ใช้เทมเพลตของ Xcode เพื่อเริ่มต้นกับโค้ดตัวอย่าง
  4. เพิ่มรหัสเพื่อรองรับความตั้งใจของ Siri
  5. กำหนดค่าคำศัพท์ของ Siri ผ่าน plist s

ไม่ต้องกังวล: เราจะอธิบายแต่ละข้อนี้ โดยจะอธิบายส่วนขยายและการให้สิทธิ์ไปพร้อมกัน

เพื่อเน้นเฉพาะส่วนต่างๆ ของ Siri ฉันได้เตรียม List-o-Mat ตัวจัดการรายการสิ่งที่ต้องทำอย่างง่าย

GIF แบบเคลื่อนไหวที่แสดงตัวอย่าง List-o-Mat
ทำรายการใน List-o-Mat (ตัวอย่างขนาดใหญ่)

คุณสามารถหาแหล่งที่มาของตัวอย่างทั้งหมด List-o-Mat ได้ที่ GitHub

ในการสร้าง ทั้งหมดที่ฉันทำคือเริ่มต้นด้วยเทมเพลตแอป Xcode Master-Detail และทำให้ทั้งสองหน้าจอเป็น UITableView ฉันได้เพิ่มวิธีการเพิ่มและลบรายการและรายการ และวิธีทำเครื่องหมายรายการเมื่อเสร็จสิ้น การนำทางทั้งหมดถูกสร้างขึ้นโดยเทมเพลต

ในการจัดเก็บข้อมูล ฉันใช้โปรโตคอล Codable (เปิดตัวที่ WWDC 2017) ซึ่งเปลี่ยนโครงสร้างเป็น JSON และบันทึกลงในไฟล์ข้อความในโฟลเดอร์ documents

ฉันตั้งใจเก็บรหัสไว้ง่ายมาก หากคุณมีประสบการณ์กับ Swift และสร้างตัวควบคุมการดู คุณก็ไม่น่าจะมีปัญหากับมัน

ตอนนี้ เราสามารถทำตามขั้นตอนในการเพิ่มการรองรับ SiriKit ได้แล้ว ขั้นตอนระดับสูงจะเหมือนกันสำหรับแอปใดๆ และโดเมนและเจตนาใดก็ตามที่คุณวางแผนจะนำไปใช้ ส่วนใหญ่เราจะจัดการกับเว็บไซต์สำหรับนักพัฒนาของ Apple แก้ไข plist และเขียน Swift เล็กน้อย

สำหรับ List-o-Mat เราจะเน้นที่โดเมนรายการและโน้ต ซึ่งใช้ได้กับสิ่งต่างๆ เช่น แอปจดบันทึกและรายการสิ่งที่ต้องทำ

ในโดเมนรายการและโน้ต เรามีจุดประสงค์ต่อไปนี้ซึ่งเหมาะสมสำหรับแอปของเรา

  • รับรายการงาน
  • เพิ่มงานใหม่ในรายการ

เนื่องจากการโต้ตอบกับ Siri เกิดขึ้นจริงนอกแอพของคุณ (บางทีแม้ในขณะที่แอพของคุณไม่ได้ทำงาน) iOS จะใช้ส่วนขยายเพื่อใช้งานสิ่งนี้

ส่วนขยายเจตนา

หากคุณไม่ได้ใช้งานส่วนขยาย คุณจะต้องรู้สามสิ่งหลัก:

  1. ส่วนขยายเป็นกระบวนการที่แยกต่างหาก มันถูกจัดส่งภายในบันเดิลของแอพของคุณ แต่มันทำงานโดยสมบูรณ์ด้วยตัวของมันเองพร้อมแซนด์บ็อกซ์ของมันเอง
  2. แอปและส่วนขยายของคุณสามารถสื่อสารกันได้โดยอยู่ในกลุ่มแอปเดียวกัน วิธีที่ง่ายที่สุดคือผ่านโฟลเดอร์แซนด์บ็อกซ์ที่แชร์ของกลุ่ม (ดังนั้น พวกเขาสามารถอ่านและเขียนไปยังไฟล์เดียวกันได้หากคุณใส่ไว้)
  3. ส่วนขยายต้องมีรหัสแอป โปรไฟล์ และการให้สิทธิ์ของตนเอง

หากต้องการเพิ่มส่วนขยายให้กับแอปของคุณ ให้เริ่มต้นด้วยการลงชื่อเข้าใช้บัญชีนักพัฒนาซอฟต์แวร์และไปที่ส่วน "ใบรับรอง ตัวระบุ และโปรไฟล์"

กำลังอัปเดตข้อมูลบัญชีแอปนักพัฒนา Apple ของคุณ

ในบัญชีนักพัฒนา Apple ของเรา สิ่งแรกที่เราต้องทำคือสร้างกลุ่มแอพ ไปที่ส่วน "กลุ่มแอป" ใต้ "ตัวระบุ" และเพิ่ม

สกรีนช็อตของกล่องโต้ตอบเว็บไซต์นักพัฒนา Apple สำหรับการลงทะเบียนกลุ่มแอพ
การลงทะเบียนกลุ่มแอป (ตัวอย่างขนาดใหญ่)

ต้องเริ่มต้นด้วย group ตามด้วยตัวระบุโดเมนแบบย้อนกลับตามปกติของคุณ เนื่องจากมีคำนำหน้า คุณจึงใช้ตัวระบุแอปเป็นส่วนที่เหลือได้

จากนั้น เราจำเป็นต้องอัปเดต ID ของแอปเพื่อใช้กลุ่มนี้และเพื่อเปิดใช้งาน Siri:

  1. ไปที่ส่วน "รหัสแอป" และคลิกที่รหัสแอปของคุณ
  2. คลิกปุ่ม "แก้ไข";
  3. เปิดใช้งานกลุ่มแอป (หากไม่ได้เปิดใช้งานสำหรับส่วนขยายอื่น)
    สกรีนช็อตของเว็บไซต์ผู้พัฒนา Apple ที่เปิดใช้งานกลุ่มแอพสำหรับ ID แอพ
    เปิดใช้งานกลุ่มแอป (ตัวอย่างขนาดใหญ่)
  4. จากนั้นกำหนดค่ากลุ่มแอปโดยคลิกปุ่ม "แก้ไข" เลือกกลุ่มแอพจากเดิม
    สกรีนช็อตของกล่องโต้ตอบเว็บไซต์นักพัฒนา Apple เพื่อตั้งชื่อกลุ่มแอพ
    ตั้งชื่อกลุ่มแอพ (ตัวอย่างขนาดใหญ่)
  5. เปิดใช้งาน SiriKit
    ภาพหน้าจอของ SiriKit ถูกเปิดใช้งาน
    เปิดใช้งาน SiriKit (ตัวอย่างขนาดใหญ่)
  6. คลิก "เสร็จสิ้น" เพื่อบันทึก

ตอนนี้ เราต้องสร้าง ID แอปใหม่สำหรับส่วนขยายของเรา:

  1. ในส่วน "รหัสแอป" เดียวกัน ให้เพิ่มรหัสแอปใหม่ นี่จะเป็นตัวระบุแอปของคุณพร้อมคำต่อท้าย อย่า ใช้เพียง Intents เป็นคำต่อท้ายเพราะชื่อนี้จะกลายเป็นชื่อโมดูลของคุณใน Swift และจะขัดแย้งกับ Intents ที่แท้จริง
    สกรีนช็อตของหน้าจอนักพัฒนา Apple เพื่อสร้าง ID แอพ
    สร้าง ID แอปสำหรับส่วนขยาย Intent (ตัวอย่างขนาดใหญ่)
  2. เปิดใช้งาน ID แอปนี้สำหรับกลุ่มแอปด้วย (และตั้งค่ากลุ่มเหมือนที่เคยทำมาก่อน)

ตอนนี้ สร้างโปรไฟล์การจัดสรรการพัฒนาสำหรับส่วนขยาย Intent และสร้างโปรไฟล์การจัดสรรของแอปของคุณใหม่ ดาวน์โหลดและติดตั้งตามปกติ

เมื่อติดตั้งโปรไฟล์ของเราแล้ว เราต้องไปที่ Xcode และอัปเดตสิทธิ์ของแอป

การอัปเดตการให้สิทธิ์แอปของคุณใน Xcode

ย้อนกลับไปใน Xcode เลือกชื่อโปรเจ็กต์ของคุณในเนวิเกเตอร์โปรเจ็กต์ จากนั้นเลือกเป้าหมายหลักของแอป แล้วไปที่แท็บ "ความสามารถ" ในนั้นคุณจะเห็นสวิตช์เปิดการรองรับ Siri

ภาพหน้าจอของหน้าจอการให้สิทธิ์ของ Xcode ที่แสดง SiriKit เปิดใช้งานอยู่
เปิดใช้งาน SiriKit ในการให้สิทธิ์ของแอพของคุณ (ตัวอย่างขนาดใหญ่)

ด้านล่างรายการ คุณสามารถเปิดกลุ่มแอปและกำหนดค่าได้

สกรีนช็อตของหน้าจอการให้สิทธิ์ของ Xcode ที่แสดงกลุ่มแอปเปิดใช้งานและกำหนดค่าแล้ว
กำหนดค่ากลุ่มแอปของแอป (ตัวอย่างขนาดใหญ่)

หากคุณตั้งค่าอย่างถูกต้อง คุณจะเห็นสิ่งนี้ในไฟล์ .entitlements ของแอปของคุณ:

ภาพหน้าจอของ plist ของ App ที่แสดงว่าสิทธิ์ได้รับการตั้งค่า
plist แสดงการให้สิทธิ์ที่คุณกำหนด (ตัวอย่างขนาดใหญ่)

ในที่สุด เราก็พร้อมที่จะเพิ่มเป้าหมายส่วนขยาย Intent ให้กับโครงการของเราแล้ว

การเพิ่มส่วนขยายเจตนา

ในที่สุดเราก็พร้อมที่จะเพิ่มส่วนขยายแล้ว ใน Xcode เลือก "ไฟล์" → "เป้าหมายใหม่" แผ่นงานนี้จะปรากฏขึ้น:

สกรีนช็อตที่แสดงส่วนขยาย Intent ในกล่องโต้ตอบ New Target ใน Xcode
เพิ่มส่วนขยาย Intent ให้กับโครงการของคุณ (ตัวอย่างขนาดใหญ่)

เลือก "ส่วนขยายเจตนา" และคลิกปุ่ม "ถัดไป" กรอกหน้าจอต่อไปนี้:

ภาพหน้าจอจาก Xcode แสดงวิธีกำหนดค่าส่วนขยาย Intent
กำหนดค่าส่วนขยาย Intent (ตัวอย่างขนาดใหญ่)

ชื่อผลิตภัณฑ์ต้องตรงกับสิ่งที่คุณสร้างส่วนต่อท้ายใน ID แอพ Intents บนเว็บไซต์นักพัฒนาของ Apple

เรากำลังเลือกที่จะไม่เพิ่มส่วนขยาย Intents UI บทความนี้ไม่ครอบคลุม แต่คุณสามารถเพิ่มในภายหลังได้หากต้องการ โดยพื้นฐานแล้ว มันคือวิธีการใส่แบรนด์ของคุณเองและรูปแบบการแสดงผลลงในผลลัพธ์ภาพของ Siri

เมื่อคุณทำเสร็จแล้ว Xcode จะสร้างคลาสตัวจัดการความตั้งใจที่เราสามารถใช้เป็นจุดเริ่มต้นสำหรับการใช้งาน Siri ของเรา

ตัวจัดการความตั้งใจ: แก้ไข ยืนยัน และจัดการ

Xcode สร้างเป้าหมายใหม่ที่มีจุดเริ่มต้นสำหรับเรา

สิ่งแรกที่คุณต้องทำคือตั้งค่าเป้าหมายใหม่นี้ให้อยู่ในกลุ่มแอปเดียวกันกับแอป เช่นเคย ไปที่แท็บ "ความสามารถ" ของเป้าหมาย แล้วเปิดกลุ่มแอป และกำหนดค่าด้วยชื่อกลุ่มของคุณ โปรดจำไว้ว่า แอปในกลุ่มเดียวกันมีแซนด์บ็อกซ์ที่สามารถใช้แชร์ไฟล์ระหว่างกันได้ เราต้องการสิ่งนี้เพื่อให้ Siri ขอไปที่แอพของเรา

List-o-Mat มีฟังก์ชันที่ส่งคืนโฟลเดอร์เอกสารกลุ่ม เราควรใช้เมื่อใดก็ตามที่เราต้องการอ่านหรือเขียนไปยังไฟล์ที่แชร์

 func documentsFolder() -> URL? { return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.app-o-mat.ListOMat") }

ตัวอย่างเช่น เมื่อเราบันทึกรายการ เราใช้สิ่งนี้:

 func save(lists: Lists) { guard let docsDir = documentsFolder() else { fatalError("no docs dir") } let url = docsDir.appendingPathComponent(fileName, isDirectory: false) // Encode lists as JSON and save to url }

เทมเพลตส่วนขยาย Intent ได้สร้างไฟล์ชื่อ IntentHandler.swift โดยมีคลาสชื่อ IntentHandler นอกจากนี้ยังกำหนดค่าให้เป็นจุดเริ่มต้น Intents ในส่วนขยายของ plist

สกรีนช็อตจาก Xcode แสดงให้เห็นว่า IntentHandler ได้รับการกำหนดค่าเป็นจุดเริ่มต้นอย่างไร
Plist ส่วนขยายเจตนากำหนดค่า IntentHandler เป็นจุดเริ่มต้น

ใน plist เดียวกันนี้ คุณจะเห็นส่วนประกาศเจตนารมณ์ที่เราสนับสนุน เราจะเริ่มด้วยรายการที่อนุญาตให้ค้นหารายการ ซึ่งมีชื่อว่า INSearchForNotebookItemsIntent เพิ่มลงในอาร์เรย์ภายใต้ IntentsSupported

ภาพหน้าจอใน Xcode แสดงว่าส่วนขยาย plist ควรแสดงรายการความตั้งใจที่จะจัดการ
เพิ่มชื่อเจตนาลงในรายการเจตนา (ตัวอย่างขนาดใหญ่)

ตอนนี้ไปที่ IntentHandler.swift และแทนที่เนื้อหาด้วยรหัสนี้:

 import Intents class IntentHandler: INExtension { override func handler(for intent: INIntent) -> Any? { switch intent { case is INSearchForNotebookItemsIntent: return SearchItemsIntentHandler() default: return nil } } }

ฟังก์ชัน handler ถูกเรียกเพื่อรับวัตถุเพื่อจัดการกับเจตนาเฉพาะ คุณสามารถใช้โปรโตคอลทั้งหมดในคลาสนี้และ return self ได้ แต่เราจะใส่แต่ละ Intent ไว้ในคลาสของตัวเองเพื่อจัดระเบียบให้ดีขึ้น

เนื่องจากเราตั้งใจที่จะมีคลาสที่แตกต่างกันสองสามคลาส ให้คลาสพื้นฐานทั่วไปสำหรับโค้ดที่เราต้องแชร์ระหว่างพวกเขา:

 class ListOMatIntentsHandler: NSObject { }

กรอบความตั้งใจต้องการให้เราสืบทอดจาก NSObject เราจะกรอกวิธีการบางอย่างในภายหลัง

เราเริ่มใช้งานการค้นหาด้วยสิ่งนี้:

 class SearchItemsIntentHandler: ListOMatIntentsHandler, INSearchForNotebookItemsIntentHandling { }

ในการตั้งค่า Intent Handler เราจำเป็นต้องใช้สามขั้นตอนพื้นฐาน

  1. แก้ไข พารามิเตอร์
    ตรวจสอบให้แน่ใจว่าได้ระบุพารามิเตอร์ที่จำเป็น และแก้ความกำกวมที่คุณไม่เข้าใจอย่างถ่องแท้
  2. ยืนยัน ว่าคำขอนั้นทำได้
    ซึ่งมักจะเป็นทางเลือก แต่แม้ว่าคุณจะรู้ว่าพารามิเตอร์แต่ละตัวดี คุณยังอาจต้องเข้าถึงทรัพยากรภายนอกหรือมีข้อกำหนดอื่นๆ
  3. จัดการ คำขอ
    ทำในสิ่งที่ได้รับการร้องขอ

INSearchForNotebookItemsIntent จุดประสงค์แรกที่เราจะนำไปใช้ สามารถใช้เป็นการค้นหางานได้ ประเภทของคำขอที่เราจัดการได้ ได้แก่ "ใน List-o-Mat แสดงรายการร้านขายของชำ" หรือ "ใน List-o-Mat แสดงรายการร้านค้า"

นอกเหนือจาก: "List-o-Mat" เป็นชื่อที่ไม่ดีสำหรับแอป SiriKit เนื่องจาก Siri มีปัญหากับยัติภังค์ในแอป โชคดีที่ SiriKit ช่วยให้เรามีชื่ออื่นและให้การออกเสียง ใน Info.plist ของแอป ให้เพิ่มส่วนนี้:

สกรีนช็อตจาก Xcode ที่แสดงว่าแอพ plist สามารถเพิ่มชื่อแอพและการออกเสียงอื่นได้
เพิ่มชื่อแอพสำรองและคู่มือการออกเสียงไปยังแอพ plist

สิ่งนี้ทำให้ผู้ใช้สามารถพูดว่า "list oh mat" และเพื่อให้เข้าใจเป็นคำเดียว (ไม่มียัติภังค์) มันดูไม่เหมาะบนหน้าจอ แต่ถ้าไม่มี Siri ในบางครั้ง Siri จะคิดว่า “List” และ “Mat” เป็นคำที่แยกจากกันและทำให้สับสนมาก

แก้ไข: การหาพารามิเตอร์

สำหรับการค้นหารายการสมุดบันทึก มีหลายพารามิเตอร์:

  1. ประเภทรายการ (งาน รายการงาน หรือบันทึกย่อ)
  2. ชื่อของรายการ
  3. เนื้อหาของรายการ
  4. สถานะเสร็จสิ้น (ไม่ว่างานจะถูกทำเครื่องหมายว่าเสร็จสิ้นหรือไม่)
  5. ตำแหน่งที่เกี่ยวข้องกับ
  6. วันที่ที่เกี่ยวข้องกับ

เราต้องการเพียงสองตัวแรกเท่านั้น ดังนั้นเราจะต้องเขียนฟังก์ชันการแก้ไขสำหรับพวกเขา INSearchForNotebookItemsIntent มีวิธีที่เราจะนำไปใช้

เนื่องจากเราสนใจเฉพาะการแสดงรายการงาน เราจะฮาร์ดโค้ดนั้นในการแก้ปัญหาสำหรับประเภทรายการ ใน SearchItemsIntentHandler ให้เพิ่มสิ่งนี้:

 func resolveItemType(for intent: INSearchForNotebookItemsIntent, with completion: @escaping (INNotebookItemTypeResolutionResult) -> Void) { completion(.success(with: .taskList)) }

ดังนั้น ไม่ว่าผู้ใช้จะพูดอะไร เราจะค้นหารายการงาน หากเราต้องการขยายการรองรับการค้นหา เราจะปล่อยให้ Siri พยายามหาสิ่งนี้จากวลีดั้งเดิม จากนั้นเพียงแค่ใช้ completion(.needsValue()) หากประเภทรายการหายไป อีกทางหนึ่ง เราอาจลองเดาจากชื่อโดยดูว่าตรงกับอะไร ในกรณีนี้ เราจะสำเร็จอย่างสมบูรณ์เมื่อ Siri รู้ว่ามันคืออะไร และเราจะใช้ที่ completion(.notRequired()) เมื่อเราจะลองความเป็นไปได้หลายอย่าง

ความละเอียดของชื่อเรื่องค่อนข้างซับซ้อนกว่าเล็กน้อย สิ่งที่เราต้องการคือให้ Siri ใช้รายการหากพบรายการที่ตรงกับสิ่งที่คุณพูดทุกประการ หากไม่แน่ใจหรือมีความเป็นไปได้มากกว่าหนึ่งอย่าง เราต้องการให้ Siri ขอความช่วยเหลือจากเราในการหาคำตอบ ในการทำเช่นนี้ SiriKit ได้จัดเตรียมชุดของความละเอียดที่ให้เราแสดงสิ่งที่เราต้องการให้เกิดขึ้นต่อไป

ดังนั้น หากคุณพูดว่า "ร้านขายของชำ" แสดงว่า Siri ตรงกันทุกประการ แต่ถ้าคุณพูดว่า "Store" Siri จะแสดงเมนูของรายการที่ตรงกัน

เราจะเริ่มด้วยฟังก์ชันนี้เพื่อให้โครงสร้างพื้นฐาน:

 func resolveTitle(for intent: INSearchForNotebookItemsIntent, with completion: @escaping (INSpeakableStringResolutionResult) -> Void) { guard let title = intent.title else { completion(.needsValue()) return } let possibleLists = getPossibleLists(for: title) completeResolveListName(with: possibleLists, for: title, with: completion) }

เราจะใช้ getPossibleLists(for:) และ completeResolveListName(with:for:with:) ในคลาสฐาน ListOMatIntentsHandler

getPossibleLists(for:) จำเป็นต้องพยายามคลุมให้ตรงกับชื่อที่ Siri ส่งถึงเราด้วยชื่อรายการจริง

 public func getPossibleLists(for listName: INSpeakableString) -> [INSpeakableString] { var possibleLists = [INSpeakableString]() for l in loadLists() { if l.name.lowercased() == listName.spokenPhrase.lowercased() { return [INSpeakableString(spokenPhrase: l.name)] } if l.name.lowercased().contains(listName.spokenPhrase.lowercased()) || listName.spokenPhrase.lowercased() == "all" { possibleLists.append(INSpeakableString(spokenPhrase: l.name)) } } return possibleLists }

เราวนซ้ำรายการทั้งหมดของเรา หากเราได้รับการจับคู่แบบตรงทั้งหมด เราจะส่งคืน และถ้าไม่ เราจะคืนค่าอาร์เรย์ของความเป็นไปได้ ในฟังก์ชันนี้ เราแค่ตรวจสอบเพื่อดูว่าคำที่ผู้ใช้พูดมีอยู่ในชื่อรายการหรือไม่ (จึงเป็นคำที่ตรงกันค่อนข้างง่าย) ซึ่งจะทำให้ "ร้านขายของชำ" ตรงกับ "ร้านขายของชำ" อัลกอริธึมขั้นสูงอาจพยายามจับคู่โดยพิจารณาจากคำที่ออกเสียงเหมือนกัน (เช่น ด้วยอัลกอริธึม Soundex)

completeResolveListName(with:for:with:) มีหน้าที่ตัดสินใจว่าจะทำอย่างไรกับรายการความเป็นไปได้นี้

 public func completeResolveListName(with possibleLists: [INSpeakableString], for listName: INSpeakableString, with completion: @escaping (INSpeakableStringResolutionResult) -> Void) { switch possibleLists.count { case 0: completion(.unsupported()) case 1: if possibleLists[0].spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() { completion(.success(with: possibleLists[0])) } else { completion(.confirmationRequired(with: possibleLists[0])) } default: completion(.disambiguation(with: possibleLists)) } }

ถ้าเราได้ผลลัพธ์ที่ตรงกัน เราจะบอก Siri ว่าเราทำได้สำเร็จ หากเราได้รับการจับคู่ที่ไม่แน่นอน เราจะบอกให้ Siri ถามผู้ใช้ว่าเราเดาถูกหรือไม่

หากเราได้หลายรายการที่ตรงกัน เราจะใช้ completion(.disambiguation(with: possibleLists)) เพื่อบอกให้ Siri แสดงรายการและให้ผู้ใช้เลือก

ตอนนี้เรารู้แล้วว่าคำขอคืออะไร เราต้องดูทั้งหมดและทำให้แน่ใจว่าเราสามารถจัดการกับมันได้

ยืนยัน: ตรวจสอบการอ้างอิงทั้งหมดของคุณ

ในกรณีนี้ หากเราแก้ไขพารามิเตอร์ทั้งหมดแล้ว เราก็สามารถจัดการคำขอได้เสมอ การใช้งาน confirm() โดยทั่วไปอาจตรวจสอบความพร้อมใช้งานของบริการภายนอกหรือตรวจสอบระดับการอนุญาต

เนื่องจาก confirm() เป็นทางเลือก เราไม่สามารถทำอะไรได้เลย และ Siri จะถือว่าเราสามารถจัดการกับคำขอใดๆ ที่มีพารามิเตอร์ที่ได้รับการแก้ไขแล้ว เพื่อให้ชัดเจน เราสามารถใช้สิ่งนี้:

 func confirm(intent: INSearchForNotebookItemsIntent, completion: @escaping (INSearchForNotebookItemsIntentResponse) -> Void) { completion(INSearchForNotebookItemsIntentResponse(code: .success, userActivity: nil)) }

ซึ่งหมายความว่าเราสามารถจัดการอะไรก็ได้

ที่จับ: Do It

ขั้นตอนสุดท้ายคือการจัดการคำขอ

 func handle(intent: INSearchForNotebookItemsIntent, completion: @escaping (INSearchForNotebookItemsIntentResponse) -> Void) { guard let title = intent.title, let list = loadLists().filter({ $0.name.lowercased() == title.spokenPhrase.lowercased()}).first else { completion(INSearchForNotebookItemsIntentResponse(code: .failure, userActivity: nil)) return } let response = INSearchForNotebookItemsIntentResponse(code: .success, userActivity: nil) response.tasks = list.items.map { return INTask(title: INSpeakableString(spokenPhrase: $0.name), status: $0.done ? INTaskStatus.completed : INTaskStatus.notCompleted, taskType: INTaskType.notCompletable, spatialEventTrigger: nil, temporalEventTrigger: nil, createdDateComponents: nil, modifiedDateComponents: nil, identifier: "\(list.name)\t\($0.name)") } completion(response) }

อันดับแรก เราค้นหารายการตามชื่อเรื่อง ณ จุดนี้ resolveTitle ได้ทำให้แน่ใจว่าเราจะได้ค่าที่ตรงกันทุกประการ แต่ถ้ามีปัญหา เรายังส่งคืนความล้มเหลวได้

เมื่อเราประสบความล้มเหลว เรามีตัวเลือกในการส่งต่อกิจกรรมของผู้ใช้ หากแอพของคุณใช้ Handoff และมีวิธีจัดการกับคำขอประเภทนี้ Siri อาจลองเลื่อนไปที่แอพของคุณเพื่อลองส่งคำขอที่นั่น จะไม่ทำเช่นนี้เมื่อเราอยู่ในบริบทเฉพาะเสียง (เช่น คุณเริ่มด้วย "หวัดดี Siri") และไม่รับประกันว่าจะทำได้ในกรณีอื่น ดังนั้นอย่าไว้ใจ

ตอนนี้พร้อมที่จะทดสอบแล้ว เลือกส่วนขยายความตั้งใจในรายการเป้าหมายใน Xcode แต่ก่อนที่คุณจะเรียกใช้ ให้แก้ไขแบบแผน

สกรีนช็อตจาก Xcode แสดงวิธีแก้ไขแบบแผน
แก้ไขโครงร่างของเจตนาเพื่อเพิ่มวลีตัวอย่างสำหรับการดีบัก

ที่นำมาซึ่งวิธีการให้แบบสอบถามโดยตรง:

สกรีนช็อตจาก Xcode แสดงกล่องโต้ตอบแก้ไขโครงร่าง
เพิ่มวลีตัวอย่างในส่วน Run ของโครงร่าง (ตัวอย่างขนาดใหญ่)

โปรดทราบว่าฉันกำลังใช้ "ListOMat" เนื่องจากปัญหายัติภังค์ที่กล่าวถึงข้างต้น โชคดีที่มันออกเสียงเหมือนกับชื่อแอปของฉัน ดังนั้นจึงไม่น่าจะเป็นปัญหามากนัก

ย้อนกลับไปในแอป ฉันสร้างรายการ "ร้านขายของชำ" และรายการ "ร้านฮาร์ดแวร์" ถ้าฉันขอรายการ "ร้านค้า" ของ Siri มันจะผ่านเส้นทางแก้ความกำกวม ซึ่งมีลักษณะดังนี้:

GIF แบบเคลื่อนไหวที่แสดง Siri จัดการคำขอให้แสดงรายการร้านค้า
Siri จัดการคำขอโดยขอคำชี้แจง (ตัวอย่างขนาดใหญ่)

หากคุณพูดว่า "Grocery Store" คุณจะได้ผลลัพธ์ที่ตรงกันทุกประการ ซึ่งจะตรงไปยังผลลัพธ์

การเพิ่มรายการผ่าน Siri

ตอนนี้เรารู้แนวคิดพื้นฐานของการแก้ไข ยืนยัน และจัดการแล้ว เราสามารถเพิ่มความตั้งใจที่จะเพิ่มรายการลงในรายการได้อย่างรวดเร็ว

ขั้นแรก เพิ่ม INAddTasksIntent ลงใน plist ของส่วนขยาย:

สกรีนช็อตใน XCode แสดงเจตนาใหม่ที่เพิ่มไปยัง plist
เพิ่ม INAddTasksIntent ให้กับส่วนขยาย plist (ตัวอย่างขนาดใหญ่)

จากนั้น อัปเดตฟังก์ชัน handle ของ IntentHandler

 override func handler(for intent: INIntent) -> Any? { switch intent { case is INSearchForNotebookItemsIntent: return SearchItemsIntentHandler() case is INAddTasksIntent: return AddItemsIntentHandler() default: return nil } }

เพิ่ม stub สำหรับคลาสใหม่:

 class AddItemsIntentHandler: ListOMatIntentsHandler, INAddTasksIntentHandling { }

การเพิ่มรายการจำเป็นต้องมีการ resolve ที่คล้ายกันสำหรับการค้นหา ยกเว้นด้วยรายการงานเป้าหมายแทนที่จะเป็นชื่อ

 func resolveTargetTaskList(for intent: INAddTasksIntent, with completion: @escaping (INTaskListResolutionResult) -> Void) { guard let title = intent.targetTaskList?.title else { completion(.needsValue()) return } let possibleLists = getPossibleLists(for: title) completeResolveTaskList(with: possibleLists, for: title, with: completion) }

completeResolveTaskList ก็เหมือนกับ completeResolveListName แต่มีประเภทที่แตกต่างกันเล็กน้อย (รายการงานแทนที่จะเป็นชื่อรายการงาน)

 public func completeResolveTaskList(with possibleLists: [INSpeakableString], for listName: INSpeakableString, with completion: @escaping (INTaskListResolutionResult) -> Void) { let taskLists = possibleLists.map { return INTaskList(title: $0, tasks: [], groupName: nil, createdDateComponents: nil, modifiedDateComponents: nil, identifier: nil) } switch possibleLists.count { case 0: completion(.unsupported()) case 1: if possibleLists[0].spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() { completion(.success(with: taskLists[0])) } else { completion(.confirmationRequired(with: taskLists[0])) } default: completion(.disambiguation(with: taskLists)) } }

มันมีตรรกะแก้ความกำกวมเหมือนกันและทำงานในลักษณะเดียวกันทุกประการ การพูดว่า "ร้านค้า" จะต้องมีความชัดเจน และการพูดว่า "ร้านขายของชำ" จะตรงกันทุกประการ

เราจะปล่อยให้ไม่มี confirm และยอมรับค่าเริ่มต้น สำหรับ handle เราต้องเพิ่มรายการลงในรายการและบันทึก

 func handle(intent: INAddTasksIntent, completion: @escaping (INAddTasksIntentResponse) -> Void) { var lists = loadLists() guard let taskList = intent.targetTaskList, let listIndex = lists.index(where: { $0.name.lowercased() == taskList.title.spokenPhrase.lowercased() }), let itemNames = intent.taskTitles, itemNames.count > 0 else { completion(INAddTasksIntentResponse(code: .failure, userActivity: nil)) return } // Get the list var list = lists[listIndex] // Add the items var addedTasks = [INTask]() for item in itemNames { list.addItem(name: item.spokenPhrase, at: list.items.count) addedTasks.append(INTask(title: item, status: .notCompleted, taskType: .notCompletable, spatialEventTrigger: nil, temporalEventTrigger: nil, createdDateComponents: nil, modifiedDateComponents: nil, identifier: nil)) } // Save the new list lists[listIndex] = list save(lists: lists) // Respond with the added items let response = INAddTasksIntentResponse(code: .success, userActivity: nil) response.addedTasks = addedTasks completion(response) }

เราได้รับรายการและรายการเป้าหมาย เราค้นหารายการและเพิ่มรายการ เรายังต้องเตรียมการตอบกลับสำหรับ Siri เพื่อแสดงพร้อมกับรายการที่เพิ่มและส่งไปยังฟังก์ชันการทำให้สมบูรณ์

ฟังก์ชันนี้สามารถจัดการกับวลีเช่น "ใน ListOMat เพิ่มแอปเปิ้ลในรายการซื้อของ" นอกจากนี้ยังสามารถจัดการกับรายการเช่น "ข้าว หัวหอมและมะกอก"

สกรีนช็อตของเครื่องจำลองที่แสดง Siri เพิ่มรายการลงในรายการร้านขายของชำ
Siri เพิ่มสินค้าสองสามรายการในรายการร้านขายของชำ

ใกล้เสร็จแล้ว ตั้งค่าเพิ่มเติมอีกเล็กน้อย

ทั้งหมดนี้ใช้งานได้ในโปรแกรมจำลองหรืออุปกรณ์ในพื้นที่ของคุณ แต่ถ้าคุณต้องการส่งข้อมูลนี้ คุณจะต้องเพิ่มคีย์ NSSiriUsageDescription ลงใน plist ของแอป พร้อมด้วยสตริงที่อธิบายสิ่งที่คุณใช้ Siri เพื่อ บางอย่างเช่น "คำขอของคุณเกี่ยวกับรายการจะถูกส่งไปยัง Siri" ก็ใช้ได้

คุณควรเพิ่มการโทรไปที่:

 INPreferences.requestSiriAuthorization { (status) in }

ใส่สิ่งนี้ใน viewDidLoad ของตัวควบคุมมุมมองหลักของคุณเพื่อขอการเข้าถึง Siri จากผู้ใช้ This will show the message you configured above and also let the user know that they could be using Siri for this app.

A screenshot of the dialog that a device pops up when you ask for Siri permission
The device will ask for permission if you try to use Siri in the app.

Finally, you'll need to tell Siri what to tell the user if the user asks what your app can do, by providing some sample phrases:

  1. Create a plist file in your app (not the extension), named AppIntentVocabulary.plist .
  2. Fill out the intents and phrases that you support.
A screenshot of the AppIntentVocabulary.plist showing sample phrases
Add an AppIntentVocabulary.plist to list the sample phrases that will invoke the intent you handle. (ตัวอย่างขนาดใหญ่)

There is no way to really know all of the phrases that Siri will use for an intent, but Apple does provide a few samples for each intent in its documentation. The sample phrases for task-list searching show us that Siri can understand “Show me all my notes on <appName>,” but I found other phrases by trial and error (for example, Siri understands what “lists” are too, not just notes).

สรุป

As you can see, adding Siri support to an app has a lot of steps, with a lot of configuration. But the code needed to handle the requests was fairly simple.

There are a lot of steps, but each one is small, and you might be familiar with a few of them if you have used extensions before.

Here is what you'll need to prepare for a new extension on Apple's developer website:

  1. Make an app ID for an Intents extension.
  2. Make an app group if you don't already have one.
  3. Use the app group in the app ID for the app and extension.
  4. Add Siri support to the app's ID.
  5. Regenerate the profiles and download them.

And here are the steps in Xcode for creating Siri's Intents extension:

  1. Add an Intents extension using the Xcode template.
  2. Update the entitlements of the app and extension to match the profiles (groups and Siri support).
  3. Add your intents to the extension's plist .

And you'll need to add code to do the following things:

  1. Use the app group sandbox to communicate between the app and extension.
  2. Add classes to support each intent with resolve, confirm and handle functions.
  3. Update the generated IntentHandler to use those classes.
  4. Ask for Siri access somewhere in your app.

Finally, there are some Siri-specific configuration settings:

  1. Add the Siri support security string to your app's plist .
  2. Add sample phrases to an AppIntentVocabulary.plist file in your app.
  3. Run the intent target to test; edit the scheme to provide the phrase.

OK, that is a lot, but if your app fits one of Siri's domains, then users will expect that they can interact with it via voice. And because the competition for voice assistants is so good, we can only expect that WWDC 2018 will bring a bunch more domains and, hopefully, much better Siri.

อ่านเพิ่มเติม

  • “SiriKit,” Apple
    The technical documentation contains the full list of domains and intents.
  • “Guides and Sample Code,” Apple
    Includes code for many domains.
  • “Introducing SiriKit” (video, Safari only), WWDC 2016 Apple
  • “What's New in SiriKit” (video, Safari only), WWDC 2017, Apple
    Apple introduces lists and notes
  • “Lists and Notes,” Apple
    The full list of lists and notes intents.