Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 1997

XCode :: ทำการ Inject Object จาก Storyboard กัน

$
0
0

1-bQCSLKNrW3ROh34pl2_Jww

1-bQCSLKNrW3ROh34pl2_Jww เนื่องจากมีโอกาสได้แบ่งปันเรื่อง MVP pattern ให้ทีมนิดหน่อย (แบบไม่ตั้งใจ) ซึ่งมีเรื่องหนึ่งที่ติดค้างไว้ก็คือ การ Inject Object จาก Storyboard ไปเลย จะได้ไม่ต้องมาสร้าง object ขึ้นมาใน ViewController เอง ทำให้การเขียน code ง่าย และ สะดวกขึ้น

จากตัวอย่าง code ในวันนี้อยู่ที่ Github

ซึ่งไปดูในไฟล์ ViewController.swift จะพบว่า function sort() ทำการสร้าง object จาก class SortController ขึ้นมา ดังนี้ [gist id="21d27ef67c97335aff1a4cc05dfec5e3" file="ViewController.swift"] คำอธิบาย class SortController นั้นคือ Presenter หรือตัวแทนการทำงาน หรือเป็นส่วน business logic ของระบบนั่นเอง ซึ่งจากตัวอย่างจะทำการเรียงลำดับข้อมูลตัวอักษร ดังนั้นเราจึงพยายามแยกการทำงานออกมาจาก ViewController

จากการสร้าง object ของ SortController นี่เอง

จึงมีคำถามว่า ถ้าเราไม่อยากมาสร้าง object แบบนี้ล่ะ เนื่องจากไม่ต้องการให้ code ผูกมัดจนเกินไป (Tight coupling) มันมีวิธีอื่น ๆ อีกไหม ? ซึ่งตอบได้เลยว่ามีหลายวิธีมากเช่น
  • เขียนเอง
  • ใช้ library เกี่ยวกับ dependency injection
รวมทั้งวิธีที่ผมใช้คือ Inject ผ่าน Storyboard กันไปเลย แต่ต้องแก้ไข code นิดหน่อย มาเริ่มกันเลย ขั้นแรกแก้ไขไฟล์ SortController.swift ให้ extends มาจาก NSObject ก่อน [gist id="21d27ef67c97335aff1a4cc05dfec5e3" file="SortController.swift"] ขั้นที่สองทำการแก้ไขไฟล์ ViewController.swift ให้ทำการเพิ่มตัวแปรชนิด SortController เข้ามาดังนี้ [gist id="21d27ef67c97335aff1a4cc05dfec5e3" file="ViewController02.swift"] ขั้นที่สามสร้าง Object ขึ้นมา และ เพิ่มเข้ามายัง Storyboard ทำการเลือกชื่อ class เป็น SortController ซะ แสดงดังรูป xcode-01 ขั้นตอนที่สี่ทำการเชื่อมโยงระหว่าง object ใน Storyboard กับตัวแปรใน ViewController แสดงดังรูป xcode-02 ขั้นตอนที่ห้าถ้า run ระบบจะพังตอนเปิดขึ้นมา เนื่องจากจะทำการสร้าง object ของ SortController ขึ้นมา ด้วยการเรียกผ่าน init() ซึ่งใน code ไม่มี ดังนั้นจำเป็นต้องสร้างขึ้นมา หรือลบ init() ที่เราไม่ออกไป ซึ่งผมเลือกการลบทิ้งไป ผลที่ตามมาจากการลบไปนั้น พบว่าระบบสามารถ run ขึ้นมาได้ แต่ไม่สามารถใช้งานได้ เนื่องจากเกิด error ดังนี้ [code] fatal error: unexpectedly found nil while unwrapping an Optional value [/code] ขั้นตอนที่หกทำการแก้ไขด้วยการแก้ไข code เปลี่ยนจากการ Injection แบบเดิมคือ Constructor Injection มาเป็น Property หรือ Setter Injection ซะ ซึ่งเป็นการ injection ที่นิยมใน framework ต่าง ๆ ดังนั้นจึงทำการแก้ไขดังนี้ [gist id="21d27ef67c97335aff1a4cc05dfec5e3" file="ViewController03.swift"] แต่ยังไม่จบนะ !! ลอง Run Test ของระบบนี้สิ แล้วจะพบว่าตายเรียบ เนื่องจากเราเปลี่ยนวิธีการพัฒนานั่นเอง ดังนั้นจงแก้ไขซะดี ๆ ขั้นตอนที่เจ็ดแก้ไข test ทั้งหมด และ ปรับชื่อให้อ่านง่ายขึ้น รวมทั้งอย่างลืมเรื่อง SwiftLint ด้วยว่าต้องมีค่าเป็น 0 นะ นั่นคือไม่มี warning ใด ๆ เลย เพียงเท่านี้ก็สามารถแก้ไขและปรับมาใช้การ Inject Object ผ่านทาง Storyboard ได้แล้ว สามารถดู code จากการแก้ไขได้ที่ Github::Up1

Viewing all articles
Browse latest Browse all 1997

Trending Articles