Tag Archives: Swift

Vapor

ไม่ได้เขียน blog ทาง  technical หลายเดือน เพราะในช่วงนี้ผมต้องเขียน api backend  สำหรับ mobile app ตัวหนึ่ง หลังจากการลองผิด ลองถูกอยู่นาน ก็เลยเลือกเขียนด้วย Vapor และบทความนี้ ผมคงไม่ได้เขียน tutorial การใช้ vapor อย่างเช่นให้แสดง Hello world อะไรง่ายๆแบบนั้น แต่ผมจะมาเล่าให้ฟังถึง ปัญหา , สิ่งที่เจอ , feature ต่างๆจากที่ได้ลองเขียน Vapor มาประมาณเดือนหนึ่ง

ก่อนจะเล่าถึง Vapor ผมขอย้อนกลับไปก่อนแล้วกันว่าทำไมถึงเลือกเขียน backend ด้วย swift เผื่อเป็นข้อมูลในการตัดสินใจสำหรับคนจะใช้ Vapor เป็น backend

คือในช่วงหลายเดือนที่ผ่านมา ผมได้ทำโปรเจคอยู่ตัวหนึ่ง ซึ่งเป็นโปรเจคใหญ่ที่ประกอบไปด้วยโปรเจคย่อยๆสามอย่างหลักๆด้วยกันคือ อย่างแรกเป็น api backend ทำหน้าที่เป็นตัว core service หลัก ในส่วนต่อมาคือ web front end  และสุดท้ายคือ mobile app ซึ่งสองตัวหลังนี้จะเชื่อมต่อไปยัง api backend ตัวเดียวกัน

ในช่วงที่เริ่มโปรเจค ด้วยความที่ไม่เคยทำ backend มาก่อน จึงได้ตัดสินใจเลือกที่จะใช้ Go Language ตามคำแนะนำของเหล่าทวยเทพ และเหล่า Gopher เซียน backend ว่ามัน เจ๋งงงง สุดยอด .. ดีกว่า  NodeJS, เป็น type safty, ทำงานได้เร็วมาก, concurrency เจ๋งๆ,  blah blah ๆ ชาบู Google อะไรก็ว่ากันไป

ด้วยความที่ไม่เคยเขียน Go มาก่อน ก็ต้องมาเริ่มต้นเขียน  Go และเรียนรู้ คอนเซ็ปของ Go อย่างเช่น go pointer ที่ไม่เหมือน c pointer หรือการที่มันเป็น paradigm แบบ structure ไม่ใช่แบบ OOP ที่คุ้นเคย รวมไปถึงสไตล์การเขียนอะไรย่อๆ อย่างชื่อตัวแปร ตามสไตล์ Go ซึ่งมันขัดกับสาย Swift ที่ชอบเขียนชื่อยาวๆ (แอบ แซะไปเยอะ 555+) จะอะไรก็ตาม นั่นไม่ใช่ปัญหาใหญ่สำหรับผม เพราะผมเรียนรู้มันได้

แต่ปัญหาหลักๆที่ผมเจอคือ ปริมาณงานที่ต้องทำมันเยอะมาก .. มันทำไม่ทัน เมื่อมันทำไม่ทันดังนั้น ผมจึงตัดสินใจที่จะหา Developer และ Freelance เพิ่ม แต่ปัญหาที่ใหญ่มากคือ .. คนที่เขียน Go มีน้อยมากกกกก ย้ำว่า น้อยยยยมาก  ในระยะเวลกลายเป็นว่า โปรเจคมันดีเลย์ไปหลายเดือนมาก เพราะคนไม่พอ จะไปจ้างคนเขียน ก็หาคนยากมากกก นี่ผมใช้เวลาไป 3 เดือน ยังไม่ได้ซักคน

ทำไงดีละ ?

อย่างที่บอกไปคือ โปรเจคมันทั้งหมด 3 ส่วนคือ  web front end กับ backend  แล้วก็มีส่วน mobile app ดังนั้น ผมจึงเอา api บางส่วนที่ mobile ต้องใช้งาน แยกออกมาเขียนเป็นอันใหม่ กลายเป็น backend 2 ตัว (เหมือนงานจะเพิ่ม แต่เดี๋ยวผมมีเหตุผลที่แยกออกมา ซึ่งจะกล่าวต่อไป) ในส่วนของ web front end ก็ยังเชื่อมต่อกับ backend ที่เขียนด้วย  GO เหมือนเดิม จะมีก็แต่ mobile app ที่มันจะเชื่อมต่อกับ backend ตัวใหม่ที่เขียนด้วย swift

การเริ่มต้นใหม่นี้ ผมเลือกเอา Swift มาเขียนเป็น backend ก็นับว่าความเสี่ยงอยู่มาก เพราะด้วยตัวภาษา Swift เองที่มันเปลี่ยนอยู่ตลอด และยังเป็นเรื่องค่อนข้างใหม่สำหรับการนำเอา swift มาใช้เขียนเป็น backend ผิดกับภาษา GO, Node ที่ได้ออกแบบมาสำหรับ การเขียน backend โดยเฉพาะ

มีคนถามผมนะว่า ในเมื่อมันเสี่ยง ทำไมเลือกเอา Swift ละ ไม่ใช้ Node , PHP , Ruby, JAVA บลาๆๆๆๆ ?

ผมเลือกใช้ Swift ด้วยปัจจัยหลักๆคือ

  • Node, PHP, Ruby สำหรับผม ต้องเรียนรู้ใหม่ กว่าจะทำความเข้าใจ เขียนให้คล่อง โปรเจคก็คงเลื่อนไปอีก
  • แม้ว่าจะเขียน Java พอได้ และ Java ก็มีเฟรมเวิร์คทาง backend หลายตัวเช่น spring boot แต่ผมไม่ชอบ JAVA เป็นการส่วนตัว (ผมเขียน Android ด้วยนะ แต่ใช้ Kotlin) ดังนั้นการเลือกใช้ Java จึงไม่ใช่คำตอบสำหรับผม
  • จำนวนคนที่เขียน Swift เป็นนั้น มีเยอะกว่า Go ในกรณีที่เราต้องจ้าง Freelance , Outsource นั้น หาคนง่ายกว่ามาก
  • Backend ที่จะเขียนใหม่ เป็นของ mobile ถ้าหากต้องแก้ไข ก็ให้ Mobile Dev แก้ไขทันที เพราะใช้ภาษาเดียวกัน ( Full-Stack )

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

Vapor

ก่อนหน้านี้ผมเคยลอง Kitura มาสักพัก แต่หลายๆของ Kitura มันยังไม่ค่อยโอเค เท่าไหร่ อย่างเช่น การเชื่อมต่อ postgres และสุดท้ายก็นั่นแหละ มันก็มาลงเอยด้วยการใช้ vapor และหลังจากการเขียน Vapor มาสักพัก ผมจะเล่าถึงประสบการณ์ ที่ได้ใช้ Vapor เป็น API และสิ่งต่างๆที่ได้เจอออกเป็นหัวข้อละกันนะครับ และเนื่องจากผมใช้มันเป็น API Backend ไม่ได้ใช้เป็น Web Server ดังนั้นในส่วนที่เกี่ยวข้องกับ web อย่าง server rendering , web template นี่ผมขอไม่พูดถึงนะครับ

Tools

Vapor มีเครื่องมืออำนวยความสะดวกมาให้ คือ Vapor Command Line ซึ่งมันจะช่วยให้เราเริ่มต้นสร้างโปรเจคได้ง่าย เลือกได้ว่าจะเอา template แบบไหน เป็น web หรือ แค่ api และมันยังมีคำสั่งในการ update package , dependency ต่างๆ รวมอยู่ในตัวเอง รวมไปถึงการสร้าง xcode project คืออันที่จริงเราไม่ต้องใช้ xcode project เพราะ backend มันมักจะถูก compile และทำงานบน linux (คงไม่มีใครใช้ Mac OS เป็น Server กันเท่าไหร่จริงไหม ?) แต่เราต้องวาง source code folder อะไรต่างๆให้ให้ถูกต้อง แต่เหตุผลหลักที่เรายังต้องการ xcode project เนี่ย ก็เพราะว่า เราพัฒนาบน Mac เป็นหลัก การใช้ Xcode เป็นเครื่องมือในการเขียน code มันดีกว่าการไปเขียนด้วย text editor ตัวอื่นๆ และถ้าหากเราไม่ใช้ command line tool  คุณก็ต้องมาจัดการ กับ dependency และ source code ใน xcode project ด้วยตัวเอง ซึ่งมันเสียเวลา ดังนั้นการที่มีเครื่องมือมาให้ นับว่าเป็นข้อดีอย่างมาก

Code Style

ในการเขียน backend นั้นจะมี framework หลักๆ อยู่หลายเจ้า อย่างเช่น Kitura ของ IBM หรืออาจจะเป็น Perfect และ Zewo อะไรก็ว่ากันไป แต่ถ้าหากเทียบกันแล้ว Vapor นั้นมีการเขียน coding style ที่ดูเหมือนจะเป็นสไตล์ swift มากกว่าเจ้าอื่นๆ .. อย่างกรณีของ Kitura นั้น ได้ออกแบบมาให้เหมือนกับ express ของ Node JS ดังนั้นแล้ว วิธีการในการเขียนมันก็เลย เหมือนเขียน NodeJS  ผมว่า Vapor นี้มันเข้ากับสไตล์ของผมมากกว่า

Database Support

ในการเขียน backend แน่ๆคือมันต้องเชื่อมต่อกับ database สักตัว ข้อดีที่เห็นได้ชัดมากคือ มันมี framework ที่เรียกว่า fluent ซึ่งเราไม่ต้องไปจัดการเขียน code พวก sql เอง เราสามารถสร้าง model เพื่อให้มัน จัดเก็บลง database ได้เลย  และมันก็รองรับ postgres , mongo, sqlite โดยจะทำงานผ่านสิ่งทีเรียกว่า provider และข้อดีอีกอย่างของ fluent คือเขียน unit test ง่าย (ถ้าใครเคยเขียน  unit test ที่เชื่อมต่อกับ database จะเข้าใจว่ามันปวดหัวแค่ไหน)

JSON Suport

ข้อดีอีกอย่างของ fluent คือมันแปลง json เป็น model ได้ค่อนข้างง่าย รวมไปถึง การเปลี่ยน model กลับไปเป็น json ก็ง่าย มันสะดวกมากเวลาที่จะตอบ response กลับไปเป็น json

Authentication

การยืนยันตัวตน เป็นฟีเจอร์ที่แทบจะทุก service ต้องมี ซึ่งใน vapor มันจะทำงานผ่านทาง provider (เหมือนกับกรณี database) และมันก็รองรับการ authen หลายอย่างมาก ไม่ว่าจะเป็นจะเป็นแบบ username – password หรือว่า ใช้ token ก็ได้ และรองรับ JWT ด้วย ซึ่งตรงนี้ผมว่ามันค่อนข้างสะดวก ผมยังไม่เคยลองทำพวก third party authen นะ อย่างเช่น facebook , google ว่ามันทำงานได้ดีแค่ไหน

Route

การสร้าง Route ของ Vapor นั้นก็ค่อนข้างจะง่าย ไม่ว่าจะเป็นแบบ Rest หรือแบบ static path การเข้าถึง query หรือ parameter ของ request ที่เข้ามาก็มีฟังก์ชั่นมาครบ หรือถ้าหากต้องการจะกำหนด สิทธิการเข้าถึงแต่ละ path ก็ทำได้ค่อนข้างสะดวก

REST

หากต้องการจะให้ api เป็น แบบ rest ตัวของ vapor เองก็ทำได้ง่ายๆผ่านทาง controller builder ยิ่งถ้าใช้ร่วมกับ fluent แล้ว มันเป็นอะไรที่แจ่มมาก เพราะมันลดงานในการเขียน code ลงไปได้เยอะมาก แค่กำหนดว่า PUT , POST , UPDATE เรียกฟังก์ชั่นอะไรก็จบละ (คือมันลดการเขียน code DB sql แล้วยังลดการเขียน code ในส่วนของ route อีก)

Middleware

ใน vapor มี middleware ให้ใช้งานอยู่หลายตัว อย่าง redis ,facebook auth , realm และการเขียน middle ware ขึ้นมาใช้งานเอง ผมว่ามันง่ายนะ เพราะว่ามันมี protocol รองรับไว้อยู่แล้ว

Deployment

ในส่วนของการ deploy นั้น ตัว vapor เราจัดการ environment ได้ด้วย config ไฟล์ ซึ่งใน Vapor นี้มัน แยก มาให้เราเลยว่า เป็น development, staging หรือว่า production มันทำให้ เรากำหนดสิ่งต่างๆที่จำเป็นได้สะดวกมาก อย่างเช่นว่า ตอนพัฒนา ให้มันไปต่อกับ DB เครื่องตัวเอง แต่ตอน deploy จริงๆให้มันไปต่อกับ AWS แบบนี้ รวมไปถึงการจัดการ secret key ต่างๆ มันก็แยกให้เรา

หรือถ้าอยากจะ deploy เป็นแบบ container ผ่านทาง docker ก็ทำได้ คือตัว vapor มันมี docker file ที่ community ทำไว้ให้อยู่แล้ว ดังนั้นเราเลยไม่ต้องไปเริ่มเขียน docker file จากศูนย์

Debug

จากประสบการณ์ในการเขียน GO และ NodeJS ผมบอกได้คำเดียวสองอย่างนี้ ห่วยแตกในการ debug มาก คือในช่วงแรกๆ นี่ผมถามคนที่เขียน backend หลายคน (ทั้ง Go, NodeJS) นะว่า debug กันยังไง เค้าบอกว่า ใช้ print log ดูค่าเอา ผมนี่ถึงกับร้อง WTF !!!! คือส่วนตัวผมไม่ชอบเลยกับการที่ต้องมาดู log ว่าค่า มันเป็นอะไร แม้ว่า Go มันจะมี Debugger อย่าง Delve อยู่ แต่มันต้องมา config ให้มันทำงานร่วมกันผ่าน IDE ได้ ( ใช้ Gogland IDE อาจจะง่ายกว่า VS Code หน่อยหนึ่ง) และประสิทธิภาพของ debugger นี่ก็อ่อนด้อยมาก ในขณะที่ Swift นั้นการ debug มันง่ายมาก ถ้าหากเราทำผ่าน Xcode

Unit test

เท่าที่ลองใช้งาน ตัว vapor มัน build in พวก function ในการทดสอบ route (request / response) อยู่แล้ว ไม่ต้องไปเขียน XCTest กับแบบเพียวๆเท่าไหร่ และก็อย่างที่ได้บอกไปว่า ถ้าหากใช้ fluent การเขียน unit test จะทำได้ง่ายมาก เพราะว่า เราไม่ต้องให้มันไปเชื่อมต่อกับ database server จริงๆ แค่กำหนดให้มันสร้าง db ใน memory ในตอนที่เรา run testing เท่านั้นเอง ซึ่งในบางครั้ง มันลดการเขียน mock ไปด้วยนะ

Document / Community / Sample / Tutorial

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

Feature อื่นๆ

อันที่จริงมันมีอีกหลาย feature ที่ผมยังไม่เคยลองใช้งาน อย่างเช่น session , core หรือการใช้ให้มันเป็น web server ดังนั้นในส่วนนี้ก็เลยบอกไม่ได้ว่า เป็นยังไง

vapor.cloud

อันนี้ผมก็ไม่ได้ลองใช้งานนะครับ ที่ยกมาพูดถึงเนี่ย ผมแค่จะบอกว่า Vapor น่าจะมีอนาคตสดใสอยู่นะ เพราะว่า อาจจะเป็น cloud เจ้าแรก ที่ใช้ Swift เป็นหลัก

ข้อเสียละ ?

ข้อเสีย อย่างแรกของมันคือ เค้าบอกว่า มันทำงานได้ช้ากว่าตัวอื่นๆ ซึ่งก็มีคนลอง bench mark   ซึ่งก็มีผลว่า Vapor 2 ทำงานได้ค่อนข้างช้ากว่าคนอื่น เร็วสุดก็ Go และมั้ง แต่ว่าในส่วนนี้ผมไม่ค่อยแคร์เรื่อง performance สักเท่าไหร่ เพราะว่า จำนวนผู้ใช้งานอยู่แค่หลักพัน ไม่ได้ทำ server ที่จะรองรับผู้ใช้งาน หลักล้านคน ข้อเสียอย่างที่สองคือ ยังไม่มีค่อยมีคนเอา swift เป็น backend เจอปัญหาอาจจะต้องหาทางแก้เอาเอง

สรุป

ถ้าคุณสามารถใช้ firebase หรือพวก service สำเร็จรูปอื่นๆได้ก็ไม่ต้องเขียนเองหรอกครับ แต่ถ้าต้องเขียน backend เอง ผมว่า Vapor เป็นทางเลือกที่ดี ตัวหนึ่งเลยนะครับ เหมาะมากสำหรับทีม ที่มี iOS Dev เยอะๆ

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

Swift String กับภาษาไทย

วันก่อนๆ มีคนโพสในกลุ่มของ iOS Dev Thai เกี่ยวกับปัญหาภาษาไทยของ swift string ว่ามันไม่สามารถค้นหาคำได้อย่างที่ต้องการ ยกตัวอย่างเช่น

จากตัวอย่างง่ายๆนี้จะเห็นว่า เราสามารถหาคำว่า “ชี” ได้  แต่ในขณะที่ “ช” ตัวเดียวนั้นกลับหาไม่เจอ

ว่าแต่ทำไม มันหาไม่เจอละ ?

ปัญหาของมันก็คือว่า Swift นั้นใช้ Grahpheme ซึ่งมันจะ เอา สระ วรรณยุกต์ และ ตัวอักษร มารวมเป็นตัวเดียวกัน คือพูดง่ายๆว่ามันนับตามช่องไฟของตัวอักษร

ถ้าหากเรานับจำนวนตัวอักษร มันก็จะนับได้แบบนี้

ก็จะเห็นว่า ไม่ว่าจะเป็น ก , กู , กู้ มันก็นับได้ 1 เหมือนกัน

ในภาษาจำพวกภาษาอังกฤษ ตัวอักษณ e กับ é เขามองเป็นตัวอักษรคนละตัวอักษร

จากโค้ดข้างบน มันก็ทำงานถูกละ เพราะ e กับ é มันคนละตัวอักษร

แต่ในกรณีของภาษาไทย  เราไม่ได้นับ ช กับ ชี เป็นตัวอักษรคนละตัวกัน แต่เราบอกว่า มันคือ

  • ช ที่มี สระ อี

ดังนั้นแล้ว มันจึงเกิดปัญหาว่า เมื่อใช้เมธอด อย่าง contains เนี่ย มันเจอ “ชี” แต่กลับไม่เจอ “ช” เพราะมันมองว่าเป็นคนละตัวกัน

เราจะแก้ปัญหานี้ยังไงดี

วิธีการแรก คือ ใช้เมธอด localizedStandardCompare เมธอดนี้ มีใช้ใน iOS9

เมธอดนี้ อาจจะแก้ปัญหาเรื่องที่ว่า มันหา “ช” ไม่เจอ

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

อย่างเช่นมี “ก” ตัวเดียว แต่ถ้าหาด้วย “กู้” มันก็จะบอกว่า เจอเหมือนกัน เช่นตัวอย่างนี้

 

วิธีการที่สองคือ เปรียบเทียบ ตาม character ไปทีละตัว โดยใช้เมธอด range(of:) แล้วก็กำหนด option ให้เป็น literal ซึ่งเราอาจจะเขียนออกมาเป็น extension ง่ายๆ แบบนี้

จะเห็นว่าผลลัพธ์นั้นให้ความถูกต้องมากกว่าวิธีการแรก
วิธีการแรก อาจจะเหมาะกับการค้นหาแบบ คร่าวๆ อย่างเช่นการ search แต่ถ้าหากต้องการผลลัพธ์ที่ถูกต้องวิธีที่สองน่าจะเหมาะสมกว่า

หวังว่าจะช่วยให้หลายคนหายสงสัยเกี่ยวกับ String ใน Swift นะครับ

What you should know about iOS Dev in 2017

2-3 เดือนหลังๆมานี่ผมไม่ค่อยได้เขียน blog เท่าไหร่ ก็ด้วยเพราะว่า มัวแต่ทำ Video Swift ที่จะเปิดสอนในปีหน้า แต่วันนี้เป็นโอกาสดีที่ผมจะเขียนเกี่ยวกับ สิ่งที่คุณควรจะรู้เกี่ยวกับ Swift และ iOS ในปี 2017 ที่จะมาถึงนี้ ..

ผมเชื่อว่า ณ ตอนนี้จำนวน iOS Dev เมืองไทย คงมีเยอะมากกว่าสมัยที่ผมเพิ่งจะเริ่มเขียน Blog นี้ สัก 100 เท่าได้มั้ง มีคนเก่งมากมายกว่าแต่ก่อน ยิ่งถ้าเนื้อหาแบบ Basic แล้วผมว่า คนทั่วๆไปก็คงน่าจะพอรู้หมดแล้วแหละ เพราะว่า เวปต่างๆ ก็มีให้อ่านมากมาย ทั้งไทย ทั้ง ตปท. นับว่า สิ่งทีดีมากครับ ยิ่งมีคนเก่งมาก เท่าไหร่ ประเทศเราจะพัฒนาเร็วเท่านั้น

ตามความตั้งใจแรกของผมคืออยากจะเขียน blog เกี่ยวกับ mac dev ตั้งแต่สมัย Apple ยังไม่ออก iPhone ด้วยซ้ำไป จนปัจจุบันมีนักพัฒนา iOS , Mac มากมาย ซึ่งมันก็บรรลุจุดประสงค์ของผมแล้ว เอาตรงๆนี่ผมยังตกใจเลยว่า นี่ผมเขียน blog นี้มาตังแต่ปี 2008 เลยเหรอ แม้ว่าจำนวน Dev จะเพิ่มมากกว่าแต่ก่อน อย่างไรก็ตาม ผมคิดว่า จำนวนไม่ใช่สิ่งสำคัญแล้ว สิ่งที่สำคัญกว่าคือ คุณภาพ ซึ่งการที่จะยกระดับ Dev ไทยให้เก่ง กว่า ณ ปัจจุบัน ได้นั่นก็คือ Dev เองนั้นควรจะรู้ว่า ตอนนี้ โลก เค้าไปถึงไหนกันแล้วบ้าง ดังนั้นผมจะขอ List สิ่งต่างๆ ที่ iOS และ Swift Dev นั้นควรจะศึกษาไว้ หรือถ้าไม่ศึกษา ก็ควรจะได้ยินคำศัพท์ พวกนี้บ้าง ซึ่งผมจะแบ่งเป็นหลายๆ หัวข้อ อธิบาย สั้นๆ ว่ามันคืออะไร ส่วนที่เหลือ ก็ไปศึกษากันเองนะครับ

Programming Paradigm

  • Protocol Oriented Programming
    สำหรับปีนี้ค่อนข้างจะมาแรงมาก คือเป็นแนวทางการเขียนโปรแกรมด้วย protocol (ส่วนตัวผมคิดว่าใช้ protocol  แบบเพียวๆไม่ได้หรอก แต่มันเป็น concept ที่ควรศึกษาไว้)
  • Functional Programming
    แม้ว่า swift ไม่ใช่ภาษา functional แบบเพียวๆเหมือนอย่าง haskell แต่ว่า swift ก็เขียนแบบ functional ได้เหมือนกัน อย่างน้อยๆคุณควรจะใช้ filter , map , reduce อะไรแบบนี้เป็นบ้าง

Tools

  • Cocoapod
    หลายคนน่าจะคุ้นเคยกันดี กับ package manager ตัวนี้ คือถ้ายังไม่เข้าใจว่ามันคืออะไร คุณควรจะศึกษามันเสียตั้งแต่วันนี้
  • Carthage
    เป็น package manger เหมือนกัน แต่มีแนวคิด ต่างออกไปจาก cocoapod เพราะมันไม่รวม repo ไว้ตรงกลาง และมันไม่ไปแก้ไข project setting ของเรา (หลังๆมานี่ผมใช้ carthage แทน cocoapod)
  • Fastlane
    มันคือ Continues Delivery Tool ตัวหนึ่ง และมันประกอบไปด้วย เครื่องมืออีกยิบย่อยมากมาย ช่วยให้เราทำงานได้เร็วขึ้น
  • Swift Package Manager
    ตัวนี้เป็น package manger ของ swift เองเลย ณ ปัจจุบันที่ผมเขียน ยังไม่รองรับ iOS แต่เหมาะสำหรับใช้งานกับ Linux
  • Swift Tool Chain
    คือถ้าใครเขียน Swift บน Linux หรือพวก Server Side อันนี้ควรจะรู้บ้าง
  • Fabric (Crashlytic , Beta)
    อันนี้ของพื้นฐานเลยนะครับ สำหรับช่วยให้เราดูได้ว่าหลังจาก ปล่อย app ไปแล้วมัน crash ตรงไหน

Architecture Pattern

  • MVC
  • MVVM
  • MVP
  • Viper

ถ้าเขียน iOS นี่อย่างน้อยคุณควรจะเข้าใจ Architecture Pattern อย่าง Model View Control (MVC) บ้างนะครับ ถ้าแม้แต่ MVC ยังไม่รู้ว่ามันคืออะไร นี่ผมว่าแย่ครับ ควรจะรีบไปศึกษาให้เข้าใจ สำหรับคนที่เข้าใจแล้ว หลังๆมานี้ ก็มีพวกโมเดล อื่นๆ ที่ควรจะรู้ไว้บ้างครับ เพราะหลายๆที่ก็เริ่มใช้โมเดลอื่นนอกจาก MVC แล้ว

Mind-Set

  • Agile
  • Continues Integration , Continues Delivery ( CI/CD)

สมัยนี้แล้ว บริษัทไหนยังทำงานแบบ waterfall อยู่อันนี้ผมว่า ควรจะลองศึกษาการทำงานแบบ agile ได้แล้วนะครับ เพราะทั่วโลกเค้าใช้วิธีการทำงานแบบนี้แทบจะทั้งนั้น (ผมไม่ได้บอกว่ามันดีที่สุดนะ อย่าง Google เองก็ไม่ได้ใช้ Agile ) นอกจากการทำงานแบบ agile แล้ว สิ่งหนึ่งที่คุณจะได้ยินบ่อยมากคือ CI/CD ควรจะศึกษาไว้ครับ

Engineering Practice

  • Unit Test
  • TDD
  • Automate Test
  • Pair Programming

ใครยังไม่เคยเขียน Unit Test เลย ควรจะลงมือศึกษามันโดยด่วน จากประสบการณ์ส่วนตัว ถ้าคุณเขียน Unit Test ไม่เป็น ผมบอกเลยว่า คุณแทบจะไม่มีโอกาสได้ทำงานกับบริษัทชั้นนำเลย (เว้นแต่ว่าคุณทำงานสาย Game การเขียน unit test , automate test นั้นไม่ค่อยมีใครทำเท่าไหร่)

Swift Server Side

  • IBM Kitura
  • Vapor
  • Perfect

ตอนนี้ก็มีหลายบริษัท กำลังเอา Swift ไปเขียน backed ผมว่านี่เป็นโอกาสที่ดี ทีคุณน่าจะลองศึกษา swift สำหรับ server บ้างครับ ส่วนตัวผมเคยลองเล่นทั้ง Kitura กับ Vapor ก็คิดว่า ในปีหน้านี้ มันมาแน่ๆครับ

Platform / Service

  • Firebase
  • AWS
  • Realm
  • Heroku

ถ้าเอ่ยชื่อ  firebase แล้ว คนที่ทำ mobile ฝั่ง android น่าจะรู้จักดี แล้วก็ไม่ได้จำกัดแค่ใน android  นะ ใน iOS ก็ใช้ได้เหมือนกัน นอกจากนั้นก็มีอย่างอื่นให้ลองเล่นเช่น heroku หรือ aws , แม้ว่าสิ่งเหล่านี้จะดูเหมือนเป็น server side มากกว่า mobile แต่ผมว่าควรศึกษาไว้บ้างครับ

Others Useful tools

  • Slack
  • Brew
  • Postman
  • Docker
  • Shell ( Bash / Zsh )
  • git / svn

สำหรับนักศึกษา จบใหม่ อาจจะไม่เคยใช้ git/svn ก็ควรจะเรียนรู้มันโดยเร็วครับ แต่ถ้าคุณทำงานมา 1-2 ปีแล้วยังไม่รู้จัก git , svn นี่ผมว่าคุณเป็น dev ที่ใช้ไม่ได้ครับ  และปิดท้ายด้วย tools ที่ควรจะรู้ไว้บ้าง อย่างการใช้ shell command หรือว่า postman เป็นต้น และถ้าใครยังคุยงานโดยใช้ Line นี่ผมว่าควรเปลี่ยนไปใช้  slack ได้แล้วนะครับ

ในส่วนที่ผมไม่ได้เขียนถึง ก็คือพวก Library ต่างๆอย่าง Alamofire , Quick , SwiftyJSON อะไรแบบนั้น เพราะผมคิดว่า มันแบ่งออกย่อยเป็นหมวดหมู่เยอะมากมาย  ก็เลยไม่ได้เขียนไว้ ผมแนะนำให้ไปดูที่ https://github.com/Wolg/awesome-swift

และในส่วนของการเพิ่มพูนความรู้ ขอแนะนำให้อ่านหนังสือ พวกนี้ครับ

Book

  • Clean code a handbook of agile software craftsmanship ( Robert C. Martin)
  • Functional Swift: Updated for Swift 3 (Chris Eidhof)
  • Code Complete : A Practical Handbook of Software Constructoin ( Steve McConnell)
  • Advance Swift : Update for Swift 3 (by Chris Eidhof, Ole Begemann , Airspeed Velocity )

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

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

และขอบคุณทุกคนครับ ที่ตามอ่าน blog ของผมมาโดยตลอด
สุดท้ายนี้ ขอให้ ปี 2017 ที่จะมาถึง เป็นปีที่มีความสุขครับ Happy Coding 🙂

Swift 3 @escapeing & @nonescape closure

วันก่อนๆ ได้โหลด XCode 8 มาใช้งานซึ่งมันก็มาพร้อมกับ Swift3 แน่นอนว่า ภาษามันเปลี่ยนแปลงไป ไม่ว่าจะเป็น ชนิดของข้อมูลแบบใหม่ หรือว่า syntax ภาษาใหม่ๆ และหนึ่งในนั้นคือ closure

ถ้าหากเคยเขียน โคลเชอร์ ใน Swift2 มา ก็อาจจะเห็น คีย์เวิร์ด @nonescape ผ่านตามาบ้าง

ใน Swift2 พารามิเตอร์ที่เป็นโคลเชอร์จะมีค่าเริ่มต้นเป็น escape closure ถ้าหากเขียน @nonescape กำกับไว้ ก็จะเป็นการบอกว่า closure นี้เป็น nonescape  อย่างไรก็ตาม keyword นี้ได้นำออกไปจาก Swift 3 เป็นที่เรียบร้อย เนื่องจากว่า ใน Swift3 นี้ได้กำหนดไว้ว่า โคลเชอร์มีค่าเริ่มต้นเป็น nonescape

ถึงตรงนี้หลายคนอาจจะเกาหัว แล้วร้องว่า What ? เชี่ยยยย อะไรเนี่ย .. nonescape closure , escape closure มันคืออะไรว่ะ ?

ใจเย็นๆ แป๊ะอย่าร้อง ผมจะอธิบายให้ฟังแบบง่ายๆก็แล้วกัน

closure ที่ถูกส่งเข้าเป็นพารามิเตอร์ในฟังก์ชัน ถ้า closure ถูกเรียกหลังจากทีฟังก์ชันทำงานเสร็จได้ เรียกว่า escape closure

เพื่อให้เห็นภาพง่ายๆ ว่า escape  คืออะไรก็ดูตัวอย่างต่อไปนี้ละกัน

สมมติว่า ผมเขียนฟังก์ชัน download ไฟล์รูป ซึ่งเรียกใช้ฟังก์ชัน loadData  ของ http ที่เป็น asynchronous call ประมาณนี้

เมื่อฟังก์ชัน loadData ทำงานเสร็จ ก็จะเรียกโคลเชอร์ completion  พร้อมกับส่ง image กลับไป

การทำงานของ completion ลักษณะแบบนี้ จะเรียกว่า escape เพราะว่า มันทำงานได้ แม้ว่า ฟังก์ชัน loadProfileImage จะทำการ return (แต่ http.loadData จะยังทำงานต่อไป และแน่นอนว่า completion ก็จะถูกเรียกหลังจากที่ http.loadData ทำงานเสร็จ) สรุปคือว่า แม้ว่า loadProfile จะทำงานเสร็จ มันก็ยังเรียก completion

โค้ดตัวอย่างที่เขียนไป สามารถทำงานได้ปกติใน Swift 2 เพราะ โคลเชอร์ได้กำหนดให้เป็น escape มาตั้งแต่แรกเริ่ม ไม่ต้องเขียนอะไรเพิ่มเติมทั้งสิ้น

แต่ถ้าหาก เอาโค้ดนี้ไปใช้งานกับ swift 3 ตัว  completion จะไม่ถูกเรียก เนื่องจาก ฟังก์ชัน loadProfileImage จะทำการ return ก่อน ที่ฟังชัน loadData จะทำงานเสร็จ (เพราะเป็น asynchronous ไม่ต้องรอให้ทำงานเสร็จก็ return ได้)

เมื่อ @nonescape ได้นำออกไป มันก็ถูกแทนที่ด้วย  @escaping

@escaping ใช้กำหนดให้โคลเชอร์เป็นแบบ escape คือทำงานได้แม้ว่าตัวฟังก์ชันที่เรียกมันจะทำงานเสร็จไปแล้ว

ดังนั้นหากเราต้องการให้มันเรียก completion หลังจากที่ loadData ทำงานเสร็จ ก็ต้องกำหนดให้เป็น @escaping ดังชั่นตัวอย่าง

และจะเห็นว่า @escaping นั้นเป็น Type ประเภทหนึ่ง เช่นเดียวกับ String , Int ไม่ได้เป็น parameter attribute  เหมือนอย่างแต่ก่อน

ทำไมต้อง non escape ?

Swift3 เปลี่ยนมาใช้ non escape closure ก็เพราะเรื่องประสิทธิภาพ รวมไปถึงการจัดการหน่วยความจำ เนื่องจากว่า non escape นั้น จะไม่ทำการเก็บ closure ไว้  ปัญหา retain cycle ก็น้อยลงไป  ข้อดีอีกอย่างคือเราไม่ต้องเขียน self ถ้าหาก closure เรียกฟังก์ชันของตัวเอง

นอกจากนี้แล้ว การเขียน closure ใน Swift3 นั้นจะไม่สามารถกำหนด argument label ได้

ยกตัวอย่างเช่นใน Swift2 เราอาจจะเขียนฟังก์ชั่น แบบนี้

แต่ใน Swift 3 จะแจ้งว่า error

untitled-2

เพราะใน Swift3 นั้น closure ได้กำหนดว่า ไม่ให้มี argument label ดังนั้นแล้ว เราจึงต้องเพิ่ม _ เข้ามาในโค้ด ดังเช่นตัวอย่าง

ลองทำความเข้าใจ และศึกษา Swift3 , Closure กันครับ หวังว่าจะช่วยให้หลายคนเข้าใจ closure มากขึ้น

Class and Struct

เขียน Swift ไปสักพัก ก็น่าจะพอรู้แล้วแหละว่า ในภาษา Swift มันมี  class , enum , struct   ทั้งสามอย่างนี้เพื่อเก็บข้อมูล แต่หลักๆ ที่มันแตกต่างกัน คือ enum และ struct นั้นเป็น value type ส่วน class นั้นเป็น reference type

Continue reading Class and Struct