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 หรือพูดอีกอย่างว่า จบ การทำงานไปแล้ว

โค้ดตัวอย่างที่เขียนไป สามารถทำงานได้ปกติใน 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 นั้นจะไม่สามารถกำหนด argument label ได้

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

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

untitled-2

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

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

GH 60 Keyboard Building log

หลายคนก็น่าจะพอรู้ว่าผมมีงานอดิเรกอย่างหนึ่งคือ ทำ keyboard ไว้ใช้เอง ก็อย่างที่เคยได้โพสไปในครั้งก่อนโน้น ว่าจากการเริ่มต้นด้วยการสร้าง keyboard แบบ handwire ผมก็มีโปรเจคสร้าง keyboard แบบใช้ PCB บ้าง  และมันก็มาถึงโปรเจค GH60 ซึ่งเป็น Project Opensource Hardware จากทาง GeekHack ( Keyboard Community ) อันที่จริงโปรเจคนี้ได้เริ่มมาตั้งแต่ปี 2014 แต่กว่ามันจะสมบูรณ์มาเป็นตัวปัจจุบัน (REV C) ก็ 2016

IMG_5347

โดยหลักการแล้ว ตัววงจร PCB ก็ใช้หลักการเดียวกับ Handwire ที่ผมได้ทำไปคือ มีตัว Micro Controller ตัวเดียวกัน ใช้ Firmware เหมือนกัน เพียงแต่ว่าถ้าใช้แบบ PCB เราก็ไม่ต้องมานั่งเชื่อมสายไฟ บัดกรี พวก ไอโอด และ Microcontroller เอง จะเหลือส่วนให้ บัดกรี จริงๆ คือ switch เท่านั้น

_DSC0208

ในครั้งนี้ผมได้ลองเอา Cherry  Switch สีเขียว มาใช้งาน (สวิตช์ สีเขียว ปกติจะใช้กับ space bar เพราะมันต้องการแรงกดค่อนข้างมาก)

สวิตช์สีเขียว รวมถึง Stabilizer สั่งมาจาก มาจาก Mouser ราคาไม่ได้แพงมาก แต่เจอภาษี เข้าไป ก็คือว่าแพงอยู่  แต่ถ้าคุณจะสั่ง ผมแนะนำว่าให้สั่งจากเวปพวก mechanicalkeyboards หรือ WASD ดีกว่าครับ เพราะ ปัญหาหลักที่ผมเจอตอนสั่งของจาก Mouser ก็คือว่า Mouser ไม่มี Costar Stabilizer มีแต่ Cherry Stabilizer อันนี้มันก็พอแก้ขัดได้ แต่ปัญหาอย่างที่สองเนี่ย ทำเอาปวดหัว นั่นก็คือเราต้องรู้จัก Part No. ครับ อย่างกรณี Cherry MX เนี่ย มันมีเป็น สิบๆ รหัส บางตัวใช้กับ PCB Mount (ไม่ต้องมี plate) ดังนั้นมันมีโอกาสที่เราจะสั่งผิดเยอะมาก  แต่ข้อดีของการสั่งจากเวปขายของ electronic แบบนี้ คือ ราคาถูกครับ อย่างสวิตช์ Cherry นี่ตัวละ 0.5 USD ในขณะที่เวปทั่วไปขาย 1 – 1.5 USD

_DSC0194

ส่วน Plate นั้นสั่งทำในไทย นี่แหละครับ คือมันจะมีร้านพวกทำงาน CNC อลูมิเนียม Laser Cutter ผมก็หาหลายเจ้านะ ถามๆดู ก็มีแต่รับงาน 10 ชิ้น ขึ้นไป หรือบางที่รับงานชิ้นเดียวแต่ราคาแพงมาก หาไปหามาจนกระทั่งเจอร้าน http://www.psstainlessthailand.com เค้าบอก อันเดียวก็รับทำ ผมเลยลอง email ไปถามเค้าดูว่าสั่งอันเดียวทำไหม ราคาเท่าไหร่ ผมต้องหาแผ่นอลูมิเนียมเองไหม เค้าก็บอกว่า รับทำ แผ่นอลูมิเนียมไม่ต้องหาเอง ผมก็เลยสั่งไป และราคาก็ไม่ได้แพงด้วย สรุปคือ ดีงาม (งานอาจจะไม่สวยนัก แต่ใช้ได้)

เมื่อทุกอย่างอยู่ในมือหมดแล้ว ในลำดับขั้นตอนต่อไปก็คือ เอา Switch มาใส่กับ Plate

_DSC0222

เสร็จแล้วก็ประกอบเข้ากับ PCB ใส่เข้าไปให้ตรงรู ที่เค้าเจาะไว้ให้

_DSC0224

เมื่อประกอบ switch ทุกตัวเสร็จ มันก็จะมีหน้าตาประมาณนี้

_DSC0232

ในส่วนด้านหลังก็จะเห็นว่า ช่องต่างๆ ก็จะเต็มพอดี

_DSC0244

จากนั้นก็ทำการบัดกรี และใส่ stabilizer ให้เรียบร้อย

IMG_5379

ในส่วนของ เคส นั้นผมสั่งจาก เวป alibaba express ครับ สั่งมาสองอัน สีขาว กับ ดำ (แต่ตัวที่ผมเอามาใช้กับตัวนี้คือสีขาว)

IMG_8673

คุณภาพของเคส ทีได้มาก็ถือว่า โอเค แต่เค้าไม่มี น๊อตให้นะ ต้องไปซื้อจากร้านขายน๊อต อีกที

และเมื่อประกอบเข้ากับ Keycaps สีเขียว/ขาว แล้วก็จะได้ Keyboard หน้าตาอย่างที่เห็น

IMG_6897

IMG_5401

เอามาเทียบกับ Handwire ที่เคยทำไป ก็เล็กกว่านิดหนึ่ง

IMG_5391

และสุดท้าย ลองมาวัดกับพี่ใหญ่อย่าง  Apple Extend Keyboard II  ซะหน่อย

IMG_7074

สรุป

ปัญหาหลักที่ผมเจอ ก็คือว่า Plate ผมสั่งมามันหนาไป ปกติเค้าใช้ 1.5 mm แต่ผมสั่ง 2 mm.  ด้วยความที่คิดว่าอยากให้มันทนทาน  ผมก็พบว่า มันทำให้ ใส่ stabilizer ลำบาก และไม่ลงตัว กลายเป็นต้องเอากระดาษทราย มาขัดเกลา stabilizer ให้มันบางลง เพื่อที่จะใส่ได้ ดังนั้นแนะนำว่า ควรให้มีความหนาแค่ 1.5 (+/- 0.1) นั่นแหละดีแล้ว

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

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

Review Harman/Kardon Aura

เอาละวันนี้ผมจะมารีวิว Harman/Kardon Aura นะครับ เพิ่งได้มาใหม่ๆ เลย คือจริงๆแล้วอาทิตย์ก่อน ผมไป Homepro (สาขาที่ผมไปคือ พระราม 3)  จะไปซื้อน้ำยาทำความสะอาดเครื่องซักผ้า แต่ดันผ่านบูทเครื่องใช้ไฟฟ้า คือบางสาขา Homepro มันมีส่วนขายเครื่องใช้ไฟฟ้าอยู่ เดินไปเห็นป้ายลดราคาลำโพงรุ่นนี้อยู่ 30% ไม่รอช้ารีบเข้าไปดูราคาว่ามันจริงป่าวว่ะ สรุปว่า เออมันลดจริงๆ จาก 15K เหลือ 11K โดยประมาณ สรุปว่าลดไป 4 พันบาท

แต่ก่อนจะซื้อ ผมก็ดูใน net ก่อนนะว่า ราคาจริงๆเค้าขายกันเท่าไหร่ ก็ลอง search ดูเห็นมีในเวป อย่าง jib ก็ขายที่ 15,900 บาท แล้วก็มีใน Lazada ขายแค่ 11,000 เหมือนกัน แต่พอแล้วพอเข้าไปดู มันเป็นคนละรุ่นกัน คือตัว ที่ขายอยู่มันจะเป็น  Aura Studio ซึ่งมันจะตัด พวก airplay ออกไป

จากการหาข้อมูลราคาคร่าวๆ ก็เลยตัดสินใจ ซื้อมา คือจริงๆมันก็มีลำโพงรุ่นอื่นๆเหมือนกันนะ ที่ลดราคา บางตัวซื้อหนึ่งแถมหนึ่งอย่าง JBL (คือลำโพง 4 พันแถมอีกตัวในราคา 2 พันกว่าบาท คุ้มโคตร) แต่ว่าผมสนใจรุ่นนี้เป็นพิเศษ คือส่วนตัวผมไปลองลำโพงตัว 4-5 พัน แล้วเสียงมันงั้นๆ เหมาะกับพกเอาไปเที่ยวมากกว่า เอามาไว้ฟังจริงจัง

มาดูกันเลย กล่องก็หน้าตาแบบนี้ ด้านบนขวา บอกไว้ว่า มันได้ Reddot Design ด้วยนะ (คือมันก็สวยจริงแหละ ถึงได้รางวัล)

aura1

ด้านหลังของกล่องก็ประมาณนี้

aura2

ส่วนด้านบนของกล่องจะเขียนไว้ชัดเจนเลยว่า รุ่นนี้ใช้ได้ทั้ง Airplay / Wifi / Bluetootch / AUX  แต่อย่างที่ผมได้บอกไป ถ้าเป็นรุ่น Aura Studio มันจะไม่มี Airplay แล้ว

aura3

จากนั้นก็เปิดกล่องออกมา

aura4

aura5

ภายในกล่องจะมีสายไฟ Adapter มาให้ พวกสาย Aux 3.5 ไม่แถมนะครับ ถ้าใครอยากจะต่อแบบมีสาย ก็ต้องซื้อสายมาเอง

aura6

และนี่ก็คือโฉมหน้าของ Aura ใสๆ วัยรุ่นชอบ

IMG_8275

ในส่วนด้านหลังจะเห็นว่ามี ช่องเสียบต่างๆ รวมไปถึงช่องต่อไฟ

aura7

เอาไปวางคู่กับ Macbook และ จอ Dell ก็ลงตัวทีเดียว

aura10

ดูใกล้ๆอีกรอบ

aura9

ใส กิ๊ก บาดใจ

สรุปทดสอบโดยรวม

  • จากการใช้งานโดยทั่วๆไป เสียงดีมากๆ เปิดดังสุด ก็ให้เสียงไม่แตก เบสยังนิ่ง เสียงแน่นมาก จริงๆผมแนะนำให้ไปร้าน ไปลองฟังก่อนนนะ ลำโพง เรื่องเสียงนี่แล้วแต่สไตล์ความชอบส่วนตัวเลย แต่โดยรวมตัวนี้ ใครฟัง ก็บอกว่าเสียงดี
  • การลด เพิ่มเสียง เป็นระบบสัมผัส ไม่ต้องกดปุ่ม แค่เอานิ้ว ลูบๆไปตามขอบๆ ก็ลดเสียง เบาเสียงได้แล้ว
  • การเชื่อมต่อ Bluetooth ทำได้ดี
  • การเชื่อมต่อ Airplay ก็ดี แต่บางทีมันกระตุก (ในกรณีที่เครื่องทำงานอย่างอื่น หรือเปิด net โหลดหนักๆ) เข้าใจว่าเป็นเพราะ router wifi ที่ผมใช้มันอาจจะไม่ดีเท่าไหร่ ( ของแถมมากับ AIS Fiber)
  • เสียง Airplay ดีกว่า Bluetooth นิดหนึ่ง เชื่อว่าคนทั่วไป แยกไม่ออก
  • ถ้าต่อ Bluetooth เสียงทุกอย่างมันจะออกที่ลำโพงหมด อย่างเช่นถ้าเปิดฟังเพลงจาก youtube ก็จะได้ยินผ่านลำโพง
  • ถ้าใช้ Airplay จะใช้ได้กับพวก iTune หรือโปรแกรมที่รองรับ Airplay ในกรณีเปิดฟังเพลงผ่าน youtube เสียงจะไปออกที่ mac แทน
  • มี iOS Application ให้ใช้ แต่ผมยังไม่ได้ลอง
  • ถ้าเทียบกับ Bose SoundLink III ผมว่าตัว Bose นั้นเสียงดีกว่าตัวนี้ นิดหนึ่ง และ bose มีขนาดเล็กกว่า แต่ Bose นั้นต่อได้เพียงแค่บลูทูช และไม่มีระบบสัมผัส  และถ้าตั้งเอาไว้ที่บ้าน ผมว่าตัวนี้มันดูสวยงามกว่าเยอะ

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

และสำหรับวันนี้ก็เท่านี้ครับ

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 ให้มันเสียเวลา

เขียนโปรแกรมกันเถิดจะเกิดผล Programming and technology