Tag Archives: Swift

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

Custom UI and Easy to customize

เมื่อเขียนโปรแกรม ios ไปเรื่อยๆสักระยะหนึ่ง สิ่งหนึ่งที่โปรแกรมเมอร์แบบเราๆ จะต้องเจอแน่ๆ นั่นก็คือ custom ui หรือการปรับแต่งหน้าตาของโปรแกรม ให้มันดู cool นั่นเอง .. ก็แน่นอนว่า วิธีที่ง่ายสุดในแต่งปรับแต่งนั่นก็คือ ให้คนอื่นทำให้เรา (แต่มันคงเป็นไปได้ยาก ใช่ม่ะ) อะๆๆ งั้นมาลองวิธีที่ง่ายกว่านั้น และนั่นก็คือ การไปใช้ ui control ของคนอื่นที่เค้าเขียนไว้แล้ว (แน่นอนละใครจะอยากไปเขียนเองให้เหนื่อย ถูกม่ะ) อย่างในเวป cocoacontrol.com ก็มีหลายอย่างให้เลือกใช้งาน

แต่ถ้ามันไม่มีละ ? (นั่นไง ซวยละ) .. สุดท้ายมันก็หนีไม่พ้นที่จะต้องเขียน custom control ถูกป่ะ ?

ผมเชื่อว่าหลายๆคน คงจะเคย custom ui กันมาแล้วแน่นอน อย่างเช่น UIButton หรือ UITableViewCell ใช่ม่ะ ถ้าใครยังไม่เคยก็คงต้องบอกว่าคุณยังไม่ใช่ iOS Dev ที่แท้จริง .. อันที่จริงการ ปรับแต่ง หรือสร้าง  control พวกนี้มันก็ไม่ใช่เรื่องยากอะไรเท่าไหร่ แต่ว่า พวก control ที่เราสร้างขึ้นมา มันมักจะปรับแต่งไม่ง่าย standard ui ที่มาพร้อมกับ XCode  เพราะว่า ui เหล่านั้น แค่ลากวาง แล้วก็กดเปลี่ยน property ใน inspector เป็นอันเสร็จพิธีเลยถูกต้องม่ะ

อย่างในรูปด้านล่างนี่ ถ้าอยากจะเปลี่ยนสีปุ่ม ก็แค่กดเปลี่ยนสีก็จบ ไม่ต้องเขียนโค้ดให้เหนื่อยเลย ให้ตายสิโรบิ้น

button

แต่ถ้าหากเป็น ui control ที่เราสร้างขึ้นมาเองละ ?

เช่น สมมติว่า เขียน control ที่เป็น ปุ่มแบบโค้งมน เราก็อาจจะเขียน control ได้ประมาณนี้

เมื่อนำไปใช้ใน Storyboard หลังจากลาก Button วางแล้ว ก็ต้องเปลี่ยนให้เป็นคลาสที่เราได้สร้างไว้

button

ถ้าให้โปรแกรมทำงาน  มันก็จะได้แบบนี้

round_button

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

เราสามารถที่จะทำให้มันมี property ปรับง่ายๆเหมือนอย่าง standard ได้ไหม ?

ผมบอกเลยว่า “ได้”

วิธีการนั้นไม่ยากเลย แค่ใช้ IBDesignable และ IBInspector เข้ามาช่วย

ซึ่งโค้ดที่ปรับใหม่ ก็จะมีลักษณะแบบนี้

เมื่อพิจารณาจากโค้ด เราได้บอกว่า คลาส RoundButton นั้นรองรับ Interface Builder และ มี inspector ทั้งหมด 3 ตัวที่สามารถปรับแต่งได้ นั่นก็คือ Border Color , Border Width และ Corner Radius

ซึ่งถ้าหากเราใช้คลาสที่สร้างขึ้นใหม่นี้ ก็จะเห็นว่า จากที่มันแสดงผลใน storyboard แบบไม่มีเส้นขอบโค้งๆ แต่ตอนนี้มันแสดงได้แล้ว

ok_button

และถ้าเข้าไปดูใน inspector ก็จะเห็นว่า มี property ใหม่เพิ่มขึ้นมา  3 อย่างด้วยกัน

prop

เป็นไง มันช่าง F**King DAMN Cool ไหมละ ?

คราวนี้อยากจะปรับอะไรก็ทำใน Storyboard ได้เลยทันที ไม่ต้องไปแก้ code ให้มันเสียเวลา