Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. iOS SDK
Code

การสร้าง SiriKit Extensions ใน iOS 10

by
Difficulty:IntermediateLength:MediumLanguages:

Thai (ภาษาไทย) translation by Anak Mirasing (you can also view the original English article)

Final product image
What You'll Be Creating

บทเร่ิมต้น

ตั้งแต่ที่ Siri ได้ถูกเปิดตัวตั้งแต่ปี 2011, เหล่าผู้พัฒนา iOS ได้ตั้งคำถามถึงความเป็นไปได้ที่จะให้แอพพลิเคชั่นของตนทำงานร่วมกับ Siri. ซึ่งในการเปิดตัว iOS 10 ในระหว่างงาน WWDC 2016, แอปเปิ้ลก็ได้เปิดตัว SiriKit เพือให้กลุ่มผู้พัฒนาได้ใช้งานเช่นกัน. แต่ถึงแม้กระนั้น ยังมีบางข้อจำกัดในเรื่องของชนิดของแอพพลิเคชั่นที่จะสามารถใช้ประโยชน์จาก Siri ได้, แต่ทั้งนี้ทั้งนั้นก็เพื่อที่จะให้การทำงานของ Siri เป็นไปในทางที่ถูกต้อง. เรามาดูกันว่า เราจะสามารถทำอะไรร่วมกับ Siri ได้บ้าง.

ข้อมูลเพิ่มเติมและฟีเจอร์ใหม่ๆ ของ SiriKit สำหรับนักพัฒนาที่พัฒนาแอพพลิเคชั่นใน iOS 10 นั้น สามารถติดตามคอร์สของ Markus Mühlberger's ซึ่งจะอยู่ในส่วนของ Envato Tuts+.

ขอบเขตที่รองรับ

ในการที่จะใช้ SiriKit นั้น, แอพของนักพัฒนาจะต้องอยู่ในขอบเขตอย่างน้อยหนึ่งข้อหรือมากกว่านั้น ตามขอบเขตเหล่านี้:

  • VoIP calling (เช่น Skype)
  • Messaging (เช่น WhatsApp)
  • Payments (เช่น Square, PayPal)
  • Photo (เช่น Photos)
  • Workouts (เช่น Runtastic)
  • Ride booking (เช่น Uber, Lyft)
  • CarPlay (สำหรับผู้ผลิตและจำหน่ายยานยนต์เท่านั้น)
  • Restaurant reservations (สำหรับการจองร้านอาหาร ซึ่งต้องการการสนับสนุนเพิ่มเติมจาก Apple)

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

สถาปัตยกรรมของ Extension(ส่วนเสริม)

SiriKit extension นั้นจะมีทั้งหมดสองชนิด.  อันแรกที่จะต้องเรียกใช้งานคือ Intents extension ซึ่งจะดูแลและจัดการคำสั่งที่มาจากยูเซอร์และดำเนินการงานในบางส่วนของแอพ เช่น เริ่มการโทรออก, ส่งเมสเสจ หรืออื่นๆ.

อีกอันคือ IntentsUI extension ซึ่งเราไม่จำเป็นต้องเรียกใช้งานก็ได้. นักพัฒนาสามารถที่จะสร้าง UI เฉพาะได้ หากต้องการให้ Siri นั้นแสดงข้อมูลตามที่นักพัฒนาต้องการ (ไว้สร้าง Custom UI). หากเราไม่ได้ทำอะไรในส่วนนี้, Siri จะแสดงอินเตอร์เฟสมาตรฐาน(Default UI)ให้โดยอัตโนมัติ. ซึ่งเราจะมาดู extension ทั้งสองชนิดนี้ในบทความนี้กันครับ.

ในช่วงของงาน WWDC 2016 แอปเปิ้ลได้ปล่อยสองวิดีโอที่น่าสนใจมากๆ เกี่ยวกับ SiriKit. คุณสามารถดูวิดีโอเหล่านั้นได้ที่นี่ ถ้าต้องการ:

โปรเจคตัวอย่าง

เราจะมาลองทำแอพตัวอย่างกัน โดยจะใช้ Siri ช่วยจัดการในส่วนของระบบชำระเงิน. ซึ่งเป้าหมายของเราในที่นี้คือจัดการจ่ายเงินด้วยประโยค "Send $20 to Patrick via TutsplusPayments" ให้ได้. รูปแบบประโยคของเราก็จะประกอบด้วยจำนวนเงินที่ระบุสกุลเงิน, ชื่อผู้รับเงินและแอพพลิเคชั่นที่ช่วยในการจัดการธุรกรรม. แล้วเดี๋ยวเราถึงจะกลับมาวิเคราะห์ถึงรายละเอียดและเจตนา(Intent)ในการทำระบบชำระเงินแบบนี้.

เริ่มทำโปรเจคกัน

เราจะเริ่มต้นด้วยการสร้าง Xcode โปรเจคโดยใช้ Swift และตั้งชื่อให้กับมัน. ซึ่งตรงนี้จะมีขั้นตอนที่เราจะต้องทำไม่กี่แห่ง เพื่อที่จะให้แอพพลิเคชั่นของเรานั้น สามารถใช้งานร่วมกับ Siri's APIs ได้.

1. เลือก your Target > Capabilities และทำการเปิดใช้งาน Siri. เราต้องมั่นใจว่า เราได้สร้าง(กำหนด)สิทธิในการใช้งานได้สำเร็จแล้วในโปรเจคของเรา.

Xcode project capabilities view

2. เปิดไฟล์ Info.plist ในแอพของเราและเพิ่มคีย์ NSSiriUsageDescription เข้าไป. ค่าของมันจะต้องเป็นข้อความที่อธิบายให้กับผู้ใช้งานเข้าใจเกี่ยวกับการขอสิทธิจากผู้ใช้งาน.

3. เลือก File > New > Target. จะมีหน้าต่างเล็กๆ แสดงขึ้นมา ให้เราเลือกไปที่ Intents Extension ซึ่งจะอยู่ใต้หัวข้อ Application Extensions. อย่าลืมเลือก Include UI Extension เข้าไปด้วย. ตรงนี้จะช่วยให้เราทำงานง่ายขึ้น หากในกรณีที่เรามีหลาย extension.

New Intents extension target

ในไฟล์ Info.plist เราจะสร้างเป้าหมายของ Intents อันใหม่เพิ่มเข้ามา เพื่อที่จะขยายการทำงานของ NSExtension ในการเรียนรู้เนื้อหาต่างๆ. ซึ่งเจ้าดิกชั่นนารีตัวนี้จะอธิบายถึงเจตนาของ extension ของเรา และยังสามารถให้ผู้ใช้เรียกใช้งานตามเจตนาในขณะที่เครื่องนั้นล็อคอยู่ได้อีกด้วย.

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

ตอนนี้เราต้องเลือกว่า เจตนาไหนที่เราต้องการให้ซัพพอร์ต. ในตัวอย่างนี้, เราได้ทำการสร้าง extension ที่จะช่วยซัพพอร์ตเจตนาในการทำธุรกรรมการเงินของเรา. เราจะแก้ไขไฟล์ Info.plist ให้ตรงตามตัวอย่างด้านล่าง.

Intents Info plist file

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

iOS Target

ในขั้นต่อไปเราจะมาลงมือเขียนโค้ดในแอพพลิเคชั่นของเราจริงๆจังๆ. จากที่เราได้ขอสิทธิการใช้งานในเรื่องเสียงเพื่อให้ Apple ได้ทำการวิเคราะห์ข้อมูลเสียงที่ได้. เราจะเริ่มต้นง่ายๆ ด้วยการอิมพอร์ต Intents เฟรมเวิร์ค และก็จะทำการเรียกเมธอดตามโค้ดดังนี้:

โดยผลลัพธ์ที่ได้จะมีไดอะล็อกแสดงขึ้นมาที่หน้าจอในครั้งแรกของการเริ่มต้นใช้งานแอพพลิชั่น ซึ่งจะมีหน้าตาประมาณนี้.

Alert that asks permission to access Siri

ซึ่งนี่คือทั้งหมดที่เราทำกันในแอพพลิเคชั่นตัวอย่างนี้. ต่อไปเรามาเข้าถึงโลกของ extensions กันเลย!.

Intents Extension

กลับมาที่ Intents extension ที่เราได้สร้างไปเมื่อกี้. เปิดส่วนของ Xcode project navigator ขึ้นมา. คุณจะเห็นไฟล์ที่ชื่อว่า IntentHandle.swift.

ไฟล์นี้จะเป็นจุดเริ่มต้นสำหรับ extension ของเราในการควบคุมเจตนาต่างๆที่ Siri นั้นส่งให้เรา. Siri จะทำการส่งต่อเจตนาทุกแบบที่ extension ของเรารองรับมาที่เมธอด handler(for:) . หน้าที่ของเราก็คือจะต้องทำการตรวจสอบชนิดของ INIntent ออปเจ็คและดูว่าจะจัดการกับมันอย่างเหมาะสมยังไง.

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

ในแต่ละ Intent(เจตนา) ที่เราได้สร้างไว้นั้นจะมีความเกี่ยวข้องกับโปรโตคอลนั้นๆ เราเองจะต้องแน่ใจว่า ในคลาสของเรานั้นได้จัดการกับเมธอดที่จะต้องถูกเรียกใช้งานตามโปรโตคอลนั้นด้วยหรือไม่. ซึ่งหลายๆโปรโตคอลใน Intents framework นั้น ก็จะมีโครงสร้างที่เหมือนๆกัน.

เราจะต้องจัดการกับโปรโตคอลที่ชื่อว่า INSendPaymentIntentHandling. โปรโตคอลนี้จะมีทั้งเมธอดที่จะต้องประกาศใช้งาน รวมทั้งเมธอดที่เป็นส่วนเสริม(จะประกาศใช้งานหรือไม่ก็ได้):

  • ต้องประกาศใช้งาน:handle(sendPayment:completion:)
  • จะประกาศหรือไม่ก็ได้:confirm(sendPayment:completion:)
    resolvePayee(forSendPayment:with:)
    resolveCurrencyAmount(forSendPayment:with:)
    resolveNote(forSendPayment:with:)

เราจะมาสร้าง extension ของ IntentHandler คลาสกันต่อในไฟล์เดิม โดยที่เราจะทำแต่เมธอดที่ต้องใช้งานเท่านั้น.

ส่วนนี้จะเป็นส่วนที่เราทำแบบง่ายๆขึ้นมา. โดยที่เราต้องแน่ใจว่า ข้อมูลของ payee(ผู้รับเงิน) และ (currencyAmount)จำนวนเงิน นั้นถูกต้อง เพื่อให้การทำธุรกรรมในแอพพลิเคชั่นของเรานั้นสมบูรณ์ได้. เราอาจจะยังไม่เชื่อว่า จริงๆตอนนี้มันพร้อมที่จะทำงานแล้ว! เลือก Intents scheme ของเราจาก Xcode แล้วทดสอบรันมันขึ้นมา. Xcode จะแสดงเมนูขึ้นมาให้เราเลือกแอพที่จะใช้งาน, ให้เราเลือกที่ Siri.

Run the extension in Xcodes menu

เมื่อ Siri พร้อมใช้งาน, เราลองพูดว่า "Send $20 to Patrick via TutsplusPayments". แจ่มแมว! ตอนนี้เราก็ได้ทำธุรกรรมการเงินสำเร็จผ่านทางเสียงโดยใช้ Siri ได้แล้ว.

First successful payment via Siri

คุณยังสามารถทดสอบในกรณีที่เกิดความผิดพลาดได้. โดยลองพูดประโยคคล้ายๆเดิม แต่ให้ตัดในส่วนของผู้รับเงินออกไป เช่น "Send $20 via TutsplusPayments". คุณจะเห็นว่า Siri จะทำงานผิดพลาดและจะจัดการด้วยการแสดงปุ่มเพื่อให้ผู้ใช้งานของเราสามารถกลับไปทำธุรกรรมในแอพพลิเคชั่นของเราใหม่ได้.

Payment failed due to missing payee name

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

ในโลกของความเป็นจริงนั้น เราควรจะสร้างเฟรมเวิร์คที่ยึดหยุ่นและสามารถใช้งานได้ร่วมกันทั้ง iOS แอพลิเคชั่นและ extensions ด้วย. การที่เราสร้างขึ้นมาด้วยสถาปัตยกรรมแบบนี้, จะทำให้เราสามารถที่จะใช้ตรรกธุรกิจ (Business Logic) ของเราได้ในหลายๆส่วน (แอพหรือ extension, อื่นๆ). เพราะเราไม่ได้ต้องการที่จะต้องทำมันขึ้นมาหลายๆครั้ง, เราต้องการที่จะทำมันขึ้นมาครั้งเดียวแต่ใช้ได้กับหลายๆโปรเจค.

Intents UI Extension

ในส่วนสุดท้ายของบทความนี้, เราจะมาทำการปรับแต่งหน้าตาที่จะให้ Siri แสดงผล เป็นไปตามแบบเฉพาะอย่างที่เราต้องการ.

ก่อนอื่น, เราคงจะจำค่าที่เราได้ตั้งไว้สำหรับเจตนา(Intent) ที่เราต้องการใช้งานในไฟล์ Info.plist ของตัว ExtensionUI , ที่เราได้ทำไปแล้วก่อนหน้านี้.

มาดูต่อที่ Intents UI extension เราจะเห็นโครงสร้างที่ทาง Xcode นั้นได้สร้างไว้ให้เรา. มันจะมี IntentViewController, ที่ซับคลาสมาจาก UIViewController ซึ่งได้ทำการ conform โปรโตคอลที่ชื่อว่า INUIHostedViewControlling ไว้อีกด้วย. เราจะมาเปิดไฟล์ Storyboard ที่ได้ถูกสร้างไว้แล้ว; เพื่อที่จะเริ่มทำการปรับแต่งหน้าตาในส่วน UI ของเรา.

เราจะใส่ UIImageView ที่พื้นหลังของแอพและจะจัดวาง label ไว้ที่ตรงกลาง เราสามารถดาวน์โหลดรูปพื้นหลังได้ที่นี่ download background image , และทำการนำมาใส่ใน intents และตั้งให้เป็นรูปที่ใช้ใน UIImageView ที่เราได้สร้างไว้แล้ว. จากนั้นเรามาสร้าง UILabel โดยจะวางไว้ที่ตำแหน่งตรงกลางของวิว. โดยเราสามารถจัดการวางสิ่งเหล่านี้ได้ง่ายๆ โดยการติดตั้ง constraints สำหรับ AutoLayout จาก Storyboard.

เปิดแท็บ Assistant Editor และสร้าง @IBOutlet สำหรับ label และตั้งชื่อว่า contentLabel . ผลลัพท์จากที่เราสร้างขึ้นด้านบนก็จะเป็นประมาณนี้:

Storyboard showing the new IntentsUI view

ทำการเปิดไฟล์ IntentViewController เราจะเห็นโค้ดตัวอย่างที่อยู่ด้านใน. เราสามารถลบอะไรก็ได้ที่เราไม่ต้องการใน configure(with:context:completion:) เมธอด ที่เรากำลังจะทำอยู่ในตอนนี้. เจ้าเมธอดนี้จะถูกเรียกเมื่อ UI ของเรานั้นพร้อมที่จะถูกตั้งค่า. อะไรบ้างในตรงนี้ที่เราต้องการที่จะตั้งค่าเนื้อหาให้กับ UILabel.

ก่อนอื่น, เรามาตรวจสอบดูที่ intent ออปเจ็คว่ามีชนิดเป็น INSendPaymentIntent. หรือไม่ ถ้ามันใช่, เราจะต้องแน่ใจว่าพรอพเพอร์ตี้ทั้งหมดที่เราต้องการใช้ในการแสดงผลนั้น จะต้องไม่เป็นค่าว่าง(nil), ไม่เช่นนั้นจะกลายเป็นว่าเราไปเรียกใช้งาน completion block ที่ทำให้ขนาดกลายเป็น 0 ซึ่งจะทำให้ custom view ของเรานั้นถูกซ่อนไป. ถ้าทุกอย่างเป็นไปตามที่เราคาดหวัง, เราจะสร้างข้อความที่มีข้อมูลที่เราต้องการให้ผู้ใช้เห็นและตั้งค่าให้กับ contentLabel

ลองรัน extension ของเราอีกครั้ง เราจะเห็นหน้าตาใหม่ที่เราได้ทำขึ้นมาของ Siri.

New custom UI in Siri extension

Siri นั้นจะแสดงผลหน้าตามาตรฐาน. ซึ่งเราสามารถซ่อนมันได้โดยการให้ view controller ของเรานั้น conform โปรโตคอลที่มีชื่อว่า INUIHostedViewSiriProviding.

จากการเราส่งค่า true กลับมาจากตัวแปล displaysPaymentTransaction, เราได้ทำการบอก Siri ว่าเราจะใช้เจ้า view controller ของเราเองในการแสดงข้อมูลสำคัญต่างๆให้กับผู้ใช้และจะทำให้ส่วนของ default view(ของ Siri) นั้นถูกซ่อนไป. และในตอนนี้ เราก็จะเห็นรูปแบบที่ชัดขึ้น!

Final result of the custom UI displayed by Siri

Note: ตามที่เราได้เห็นในรูปนั้น, เมื่อเราได้ลองใช้นามสกุลเงินอื่นๆ ที่ไม่ใช่ US ดอลล่าห์, เจ้า Siri จะเข้าใจได้อย่างถูกต้องและจะส่งโค้ดของสกุลเงินไปให้ตัว extension ของเรา. แต่น่าเสียดายจริงๆ, ที่เจ้าตัวค่าเงินจะแสดงหน่วยเป็น US ดอลล่าห์ตลอด. ซึ่งตรงนี้เราได้แจ้งในส่วนของความผิดพลาดนี้ไปยัง Apple แล้ว.

บทสรุป

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

ถ้าคุณต้องการที่จะเรียนรู้เพิ่มเติมเกี่ยวกับการพัฒนาแอพพลิเคชั่นร่วมกับ Siri หรือคุณกำลังมองหาฟีเจอร์เจ๋งๆ ของ iOS 10, คุณสามารถดูได้ที่คอร์สของ Markus Mühlberger's.

ทั้งนี้ คุณยังสามารถดูได้จากบทความสอนฟรีเกี่ยวกับฟีเจอร์ต่างๆใน iOS 10.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.