ARKit อาจดูน่ากลัว แต่ไม่ยากถ้ามีประสบการณ์พื้นฐานสร้าง iOS Apps
ผมชอบ Learn-by-doing เล่น ARKit สร้างแอปพื้นฐานฝึกมือ บทความนี้รีวิวสิ่งที่เรียนรู้จากการสร้าง Face Tracking App เรียบง่าย
แบ่ง 3 ส่วน:
- Initial Setup → ขอสิทธิ์ Camera และเช็ค Device รองรับ ARKit
- Smile Tracking → เริ่มติดตามการยิ้มด้วย ARKit สิ่งที่คุณหามา
- User Interface → เพิ่ม UI ตอบสนองต่อการยิ้ม
ขณะเขียน Xcode Simulator ไม่รองรับ Front-facing Camera ต้องใช้ Device จริง อุปกรณ์ต้องมี TrueDepth Camera (iPhone X ขึ้นไป)
โค้ดทั้งหมดอยู่บน Github สำหรับ Copy Paste Club
Initial Setup
เปิด Xcode สร้าง Project ใหม่ชื่อ "SmileTracker" (หรือชื่อที่ชอบ)
ก่อน Face Tracking ต้องทำ 2 อย่าง:
- เช็ค Device รองรับ ARKit
- ขอสิทธิ์เข้าถึง Camera
ใน Project ใหม่ เปิด ViewController.swift ใต้ import UIKit เพิ่ม: import ARKit เข้าถึง API Face Tracking ของ Apple
เพิ่มโค้ดใน viewDidLoad:
guard ARFaceTrackingConfiguration.isSupported else { fatalError("Device does not support face tracking") }ARFaceTrackingConfiguration.isSupported เป็น Boolean True ถ้า Device รองรับ Face Tracking False ถ้าไม่รองรับ กรณีไม่รองรับ Crash App ด้วย Fatal Error
ต่อไป ขอสิทธิ์ Camera เพิ่มใน viewDidLoad ใต้ Guard Statement:
AVCaptureDevice.requestAccess(for: AVMediaType.video) { granted in if (granted) { Dispatch.main.sync { // จะ Implement ฟังก์ชันนี้ในหน่อย self.setupSmileTracker() } } else { fatalError("User did not grant camera permission!") } }ขอสิทธิ์ Camera หาก User Allow รัน Function Setup Smile Tracking (ไม่ต้องกังวล Error จะ Implement ทีหลัง)
Wrap ใน Dispatch.main.sync เพราะเพิ่ม UI Elements ใน Function นี้ ต้องทำบน Main Thread
เพิ่ม Camera Usage Description ใน Info.plist เปิด Info.plist เพิ่ม Row ใหม่ (Highlight Row สุดท้าย กด Enter)
Row ใหม่ ใส่ Privacy — Camera Usage Description ใน Column Key ตั้ง Column Type เป็น String Column Value ว่างไว้หรือใส่ข้อความอธิบายการใช้ Camera
Info.plist ตอนนี้ควรเป็นแบบนี้:

ทดสอบ App จนตอนนี้ได้โดย Comment บรรทัดเรียก setupSmileTracker() จำ Uncomment ทีหลัง
รัน App ตอนนี้ควรเห็น Popup ขอ Camera Permissions ถ้ากด No ต้องไป Settings เปิด Permission ใหม่
ถ้า App Crash เช็ค Console Error 2 ข้อด้านบน
Smile Tracking
เปิด ViewController.swift เพิ่ม Variable บนสุดของ ViewController:
class ViewController: UIViewController { let sceneView = ARSCNView() override func viewDidLoad() {...} }ARSCNView มี ARSession มาพร้อม iPhone ใช้ประสาน AR Experiences ใช้ sceneView ของ ARSession วิเคราะห์ใบหน้าผู้ใช้ผ่าน Front Camera
เพิ่ม Function ใต้ viewDidLoad:
func setupSmileTracker() { let configuration = ARFaceTrackingConfiguration() sceneView.session.run(configuration) sceneView.delegate = self view.addSubview(sceneView) }สร้าง Configuration จัดการ Face Tracking ใช้ Run sceneView ของ ARSession
ตั้ง sceneView Delegate เป็น self เพิ่มเข้า View
Xcode แจ้ง Error ViewController ไม่ Conform ARSCNViewDelegate ไปที่ประกาศ ViewController บนสุด เปลี่ยนเป็น:
class ViewController: ViewController, ARSCNViewDelegate { ... }เพิ่ม Function ARSCNViewDelegate ใน Class ViewController ใต้ setupSmileTracker:
func renderer(_renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { ... }renderer รันทุกครั้ง Scene Update ให้ ARAnchor ที่ตรงกับใบหน้าผู้ใช้
Apple สร้าง ARFaceAnchor อัตโนมัติเพิ่มใน Session ตอนใช้ ARFaceTrackingConfiguration Run ARFaceAnchor นี้ส่งเข้า renderer เป็น ARAnchor
เพิ่มโค้ดใน Renderer:
func renderer(_renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { // 1 guard let faceAnchor = anchor as? ARFaceAnchor else { return } // 2 let leftSmileValue = faceAnchor.blendshapes[.mouthSmileLeft] as! CGFloat let rightSmileValue = faceAnchor.blendShapes[.mouthSmileRight] as! CGFloat // 3 print(leftSmileValue, rightSmileValue) }ใน Function นี้มีรายละเอียดมาก นับขั้นตอน (Ray Wenderlich Style)
Step 1 แปลง ARAnchor เป็น ARFaceAnchor Assign ให้ faceAnchor
ARFaceAnchor มี Info ตำแหน่ง Orientation, Topology, และ Facial Expression ของใบหน้าที่ Track
ARFaceAnchor เก็บข้อมูล Facial Expressions ใน Variable blendShapes Dictionary เก็บ Coefficients สำหรับ Facial Features ต่างๆ สนใจดูรายการเต็มใน Documentation ของ Apple (Hint: อยากเพิ่ม Frown Tracking เจอวิธีในนี้)
Step 2 ใช้ faceAnchor.blendShapes ดึง CGFloat สำหรับการยิ้มซ้ายและขวา ด้วย Key mouthSmileLeft และ mouthSmileRight
Step 3 Print ค่าทั้งสองเช็คว่าทำงาน ?
ตอนนี้ App ควร:
- ขอ Camera และ Face Tracking Permissions
- ใช้ ARKit Track Facial Expressions
- Print ค่าการยิ้มซ้ายขวาใน Console
ทดสอบว่าทำงานถูกต้อง
รัน App ครั้งแรก จะขอ Camera Permissions กด Yes
เข้าหน้าจอว่าง แต่ Console ควรเริ่ม Print CGFloat Values (อาจ Delay สั้น)
ยิ้มที่โทรศัพท์ ค่าที่ Print ควรเพิ่มขึ้น ยิ้มมาก ค่ายิ่งสูง
ถ้าทำงานถูก ยินดีด้วย ?! Error ตรวจสอบ Device รองรับ Face Tracking และ Camera Permissions เปิดอยู่ Console Print Error ทั้ง 2 กรณี
User Interface
Track ใบหน้าได้แล้ว สร้าง UI ตอบสนองการยิ้ม
เพิ่ม UILabel ชื่อ smileLabel บนสุด ใต้ sceneView
class ViewController: UIViewController { let sceneView = ARSCNView() let smileLabel = UILabel() ... }View นี้จะ React ต่อ Facial Expressions
เพิ่มโค้ดท้าย setupSmileTracker:
smileLabel.text = "?" smileLabel.font = UIFont.systemFont(ofSize: 150) view.addSubview(smileLabel) // Set constraints smileLabel.translatesAutoresizingMaskIntoConstraints = false smileLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true smileLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = trueตั้ง UI Properties พื้นฐาน smileLabel Constraints ให้กึ่งกลางหน้าจอ รัน App ควรเห็น Emoji ? ขนาดใหญ่กึ่งกลาง

เห็น Emoji แล้ว เพิ่ม Function ใน ViewController:
func handleSmile(leftValue: CGFloat, rightValue: CGFloat) { let smileValue = (leftValue + rightValue)/2.0 switch smileValue { case _ where smileValue > 0.5: smileLabel.text = "?" case _ where smileValue > 0.2: smileLabel.text = "?" default: smileLabel.text = "?" } } Function นี้เปลี่ยน Emoji ใน smileLabel ตามการยิ้ม คำนวณ smileValue จากค่าเฉลี่ยซ้ายขวาจาก ARFaceAnchor (วิทยาศาสตร์มาก)
นำค่าเข้า Switch Statement ยิ้มมาก Emoji ยิ่งมีความสุข
กลับไป renderer Function เพิ่มท้าย ส่ง Left/Right Smile Values เข้า handleSmile:
DispatchQueue.main.async { self.handleSmile(leftValue: leftSmileValue, rightValue: rightSmileValue) }ใช้ DispatchQueue อีกครั้ง เพราะเปลี่ยน UI ต้องทำบน Main Thread
รัน App ตอนนี้ Emoji ควรเปลี่ยนตามการยิ้ม
GIF ด้านล่างเพิ่มใบหน้าผมเพื่อดู Camera Output พร้อม Emoji

App ของคุณไม่มี Camera Output แต่เพิ่มได้โดย Add ARSCNView sceneView ไป Superview ให้ Dimensions
สรุป
หวังว่าบทความช่วยเริ่มสร้างแอป ARKit ได้
อยากขยาย App เพิ่ม เช็คลิสต์ Facial Features อื่นๆ ข้างบน ผมทิ้ง Hint สำหรับ Frown Tracking
กลับมา Comment โปรเจกต์ Cool ที่สร้างเอง ผมเพิ่งเริ่ม ARKit ตื่นเต้นเห็นแอปซับซ้อนกว่า
โค้ดทั้งหมดอยู่ Github สำหรับ Feedback และ Questions ขอบคุณที่อ่าน โชคดีนะ!
ขอบคุณที่อ่าน! ถ้าชอบ ติดตาม Twitter ผมโพสต์ Update เรื่อง Stories ที่กำลังทำ และกิจกรรม