Tag Archives: NSStream

Objective-C Programming Chapter 18 (Part2)

NSURLSession with Block

ทั้งสามโปรแกรมที่ได้เขียนไปใช้ delegate ในการทำงานทั้งหมด ถ้าหากไม่ได้กำหนด delegate ให้กับ session ก็สามารถใช้ block แทนได้เช่นเดียวกัน เราจะเขียนโปรแกรมเพื่อใช้ download file ซึ่งมีการทำงานเหมือนกับโปรแกรม 18.2

Program 18.4

main.m

โปรแกรม 18.4 กำหนด delegate เป็น nil หรือไม่มี delegate และการสร้าง task จะใช้เมธอด downloadTaskWithURL: completionHandler: พร้อมโค้ดในส่วนของ completion block ซึ่งจะถูกใช้งานหลังจากที่ task ได้ทำงานเสร็จสิ้นแล้ว หากดูจากโค้ดของ block จะเห็นว่าเป็นการคัดลอกไฟล์มาไว้ยัง desktop ของผู้ใช้งาน ซึ่งมีการทำงานเช่นเดียวกับ delegate ที่ได้เขียนไปในโปรแกรม 18.2 นั่นเอง

Program 18.4 Output

Download done

 

NSStream

โปรแกรม iOS หรือ Mac OS X โดยทั่วไปแล้วจะใช้โพรโทคอล HTTP ในการรับและส่งข้อมูลกับทาง web sever เช่นโปรแกรมได้เขียนกันไปก่อนหน้านี้ แต่อย่างไรก็ตามในบางครั้งอาจจะมีความจำที่ต้องใช้งานในระดับต่ำกว่า HTTP แน่นอนว่าคลาส NSURLSession ไม่สามารถใช้กับงานลักษณะแบบนี้ได้ โชคดีที่ cocoa มีคลาส NSStream ที่ได้ออกแบบมาเพื่อใช้กับงานลักษณะดังกล่าว ทำให้ไม่ต้องเขียนการทำงานในระดับต่ำๆเช่น C Socket API และอย่างเช่นเคย ก่อนที่จะเขียนโปรแกรม ควรทำความเข้าใจกับโครงสร้างการทำงานของ NSStream เสียก่อน ดังที่ได้แสดงไว้ในรูป

stream

จากรูปจะเห็นว่าไม่มีคลาส NSStream เพราะเนื่องจากคลาสนี้เป็นเพียง abstract class ส่วนคลาสที่ใช้งานจริงคือ NSInputStream ที่ทำหน้าที่ที่ใช้รับข้อมูล จากภาพจะเห็นว่า NSInputStream นอกจากจะรับข้อมูลผ่านทาง network แล้วยังสามารถรับข้อมูลจากไฟล์ หรือ NSData ได้อีกด้วย ส่วนคลาสที่ทำหน้าที่ส่งข้อมูลก็คือ NSOutputSteam ซึ่งสามารถส่งข้อมูลผ่านทาง network หรือส่งไปยังไฟล์ , หน่วยความจำ และ NSData ได้เช่นกัน
โปรแกรมที่จะได้เขียนต่อไป จะใช้คลาส NSStream เชื่อมต่อกับ echo server ที่มีการทำงานง่ายๆคือ เมื่อ client ส่งข้อความไปยังเซิฟเวอร์ ทางฝั่งเซิฟเวอร์ก็จะส่งข้อความนั้นกลับมาหา client นั่นเอง เราจะดาวน์โหลด echo server ซึ่งเขียนด้วยภาษา python ดังเช่นโปรแกรมที่ผ่านมา ได้จาก https://github.com/macfeteria/Objective-C-Demo/raw/master/Chapter%2018/Program%2018.5/echoServer.py เมื่อดาวโหลดเสร็จเรียบร้อยแล้วก็สั่งให้เซิฟเวอร์ทำงาน ด้วยการใช้คำสั่ง python echoServer.py ผ่านทาง Terminal เช่นเดิม ในส่วนของโปรแกรมฝั่ง client มีโค้ดดังนี้

Program 18.5

EchoClient.h

ในส่วนของ interface ได้ประกาศ output stream และ input stream ไว้ใช้งาน พร้อมกับเมธอดสำหรับเชื่อมต่อเซิฟเวอร์ และเมธอดที่จะใช้สำหรับส่งข้อมูล

EchoClient.m

เมธอด initCommunication นี้ทำหน้าหลักคือ สร้างอ็อบเจ็ก inputStream และ outputStream และในการสร้างอ็อบเจ็กสองอย่างนี้จะไม่ได้ใช้การ alloc เหมือนอ็อบเจ็กทั่วไป แต่จะใช้คลาสเมธอด NSStream ในการสร้าง เนื่องจากเมธอดนี้ต้องการพารามิเตอร์ที่เป็นแบบ autorelease แต่ตัวแปรที่เราได้ประกาศ นั้นเป็น strong (อ็อบเจ็กที่สร้างด้วยคลาสเมธอด หรือมีการลักษณะแบบนี้ เช่น NSError จะเป็น autorelease ทั้งหมด) ดังนั้นแล้ว จึงต้องประกาศตัวแปร oStream และ iStream ที่เป็น autorelease ขึ้นมาใช้งานเพิ่มเติม จากนั้นค่อยส่งค่าให้กับ inputStream และ outputStream ในภายหลัง เมื่อสร้างอ็อบเจ็กเสร็จเรียบร้อย ก็กำหนด run loop ที่จะใช้งาน ก็เป็นอันเสร็จสิ้น

เมธอด sendMessage นี้ทำหน้าที่ในการส่งข้อมูลผ่านทาง outputStream ส่วนการรับข้อมูลจะเขียนเมธอด stream:handleEvent ซึ่งเป็น delegate method ของ inputStream

เมื่อมีเหตุการณ์ต่างๆเกิดขึ้น เช่น ติดต่อเซิฟเวอร์ผิดพลาด หรือมีข้อมูลเข้ามายัง inputStream เมธอดนี้ก็จะถูกเรียกใช้งาน ซึ่งจะได้รับ streamEvent เพื่อบอกเหตุการณ์หรือสิ่งที่เกิดขึ้นของ stream ในเมธอดนี้สิ่งที่เราเราสนใจจริงๆ ก็คือ NSStreamEventHasBytesAvailable นั่นคือมีข้อมูลเข้ามา เมื่อได้รับข้อมูล ก็ให้ inputStream ทำการอ่านข้อมูล ส่วนกรณีอื่นๆเช่น NSStreamEventEndEncountered นี้จะเกิดขึ้นในกรณีที่การติดต่อกับทางเซิฟเวอร์ได้สิ้นสุดลง ซึ่งเราได้เขียนโค้ดให้หยุดการทำงานของ stream นั่นเอง

Summary

โปรแกรมที่ได้เขียนไปในบทนี้เป็นเพียงแค่ตัวอย่างการใช้งานพื้นฐานเท่านั้น ไม่อาจจะครอบคลุมการใช้งานคลาสต่างๆที่เกี่ยวข้องกับ Network ได้ทั้งหมด อย่างไรก็ตามผู้เขียนเชื่อว่า ตัวอย่างโปรแกรมที่ได้เขียนไปเพียงพอสำหรับการทำความเข้าใจ หลักการทำงานของคลาสต่างๆของระบบ Network ได้โดยรวม สำหรับผู้ที่สนใจศึกษาเพิ่มเติมเช่น การใช้ cache , cookie , ssl หรือ authentication สามารถศึกษาได้โดยตรงจากการอ่านเอกสารของแอปเปิ้ล ในบทหน้าเราจะเรียนรู้เทคโนโลยีสำคัญของ Mac OS X และ iOS นั่นคือ Grand Central Dispatch

 

โหลด PDF ไปอ่านได้ครับ

โหลด Source code