iPhone’s project multi-target programming

เมษายน 10, 2010 at 4:57 pm ใส่ความเห็น

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

ในการพัฒนา App ไม่ว่าจะบน Mac หรือ iPhone ก็ตาม คงจะเคยเห็นกันว่าบาง App มีหลายเวอร์ชัน เช่น Lite, Standard, Full, Pro, etc.. ซึ่งความแตกต่างส่วนมากก็มักจะเป็นเรื่องของการจำกัด Feature หรือ App บางตัวที่อยู่บน Platform Mac ก็มาอยู่บน iPhone ต่อ อย่างเช่นเกม plant vs zombie หรือ twitter client อย่าง echofon เป็นต้น

ถ้าถามหลายๆคนถึงวิธีการ Develop App พวกนี้ให้เป็นหลายๆเวอร์ชั่นดังกล่าว หลายๆคนอาจจะใช้วิธีการ Duplicate project โดยการ Copy file ทั้งโปรเจคมา แล้วเข้าไปแก้โค้ด ตัด feature ไปตามเวอร์ชั่นๆไป (ดูไม่ make sense เท่าไหร่ แต่ผมเชื่อว่ามี และเยอะด้วยที่ทำแบบนี้) ผมเองก็เคยเช่นกันครับ ทำ App 8 เวอร์ชั่นเลยทีเดียว(จริงๆก็ไม่ได้เห็นด้วย แต่เขาสั่งมาก็ต้องทำ) ปัญหาที่เจออย่างหนักหน่วงเลยก็คือ “การแก้ไข Bug ยุ่งยากและเสียเวลาเป็นที่สุด” เพราะบั๊ก 1 จุดต้องใช้เวลาเพิ่มเป็น 8 เท่าและความแน่นอนว่าการแก้แบบเดียวกันกับโปรเจคเวอร์ชั่นต่างๆกัน มันอาจใช้ไม่ได้ผลซะด้วย

ดังนั้นการทำ App หลายๆเวอร์ชั่นด้วยวิธีการ Duplicate project ไม่น่าจะเป็นทางเลือกที่ควรนัก สำหรับการทำโปรเจคหลายๆเวอร์ชั่น โดยเฉพาะตอนที่ iPad มันเริ่มเข้ามาแล้วอย่างเช่นตอนนี้ ตามจริงมันก็ไม่ควรเป็นแบบนั้นอีกเช่นกัน ในเมื่อ XCode มี Target ให้ใช้อยู่ แล้วทำไมเราถึงไม่ใช้มันล่ะ

Target คืออะไร? Target เปรียบเสมือนพิมพ์เขียวที่กำหนดค่าต่างๆในขั้นตอนการ build ผลก็คือ เราสามารถกำหนดได้ว่าตั้งแต่ target ไหนชื่ออะไร ใช้ไอค่อนตัวไหน ไฟล์ไหนบ้างที่จำเป็นต่อการ build ยันรูปแบบผลที่ได้ว่าต้องการเป็น Application หรือ static library

เวลาเรา Create project ขึ้นมาซักตัว Target จะมีมาให้โดยปรกติเลย 1 ตัว ซึ่งจะอยู่ใน Section Targets ซึ่งเราสามารถเพิ่มได้ตอนไหนก็ได้ โดยการไปที่ Menu Project > New Target… จากนั้นจะขึ้น Window ขึ้นมาให้เลือก Target แบบที่เราต้องการ จากนั้นก็ตั้งชื่อ Target ที่สร้างขึ้น กด Finished ก็เป็นอันเสร็จเรียบร้อย (ตอนนี้เรากำหนดรูปแบบได้แล้ว)

ผลที่ได้จะได้ Target อันใหม่มา 1 อันและ Plist สำหรับ Target นั้นอีก 1 ไฟล์ Plist ก็เป็นที่รู้กันว่าไว้สำหรับการตั้งค่าต่างๆเช่น icon, bundle id, bundle name, etc… ซึ่งเราก็สามารถกำหนดได้ตามต้องการ Target ตัวใหม่ก็เช่นกันเราสามารถกำหนด Framework ที่ใช้ product name, platform ของ Application, etc… ตั้งค่าได้ทั้งหมดราวกับว่ามันเป็นคนละโปรเจคนั่นแหละครับ

องค์ประกอบของ Target ก็มีต่างกันไป ใน Entry นี้ขอพูดถึงแต่แบบ Application เท่านั้นนะครับ Application จะประกอบด้วย 3 ส่วนคือ

component.png

  1. Copy Bundle Resources – เป็นส่วนของ Resource ต่างๆใน Project พวก รูปภาพ, ไฟล์เสียง, วิดีโอ, ฯลฯ
  2. Compile Sources – เป็น Source code ล้วนๆครับ เอาแต่ไฟล์ .m เท่านั้น แล้วก็สำหรับ project จะต้องมี main.m ด้วยนะครับ อย่าลืม ไม่งั้น App จะรันไม่ได้นะครับ สำคัญมาก!!
  3. Link Binary With Libraries – เป็น Framework ที่ใช้ร่วมครับ ปรกติก็จะมี UIKit.framework ตัวนึงละ (สำหรับ iPhone/iPad) หรือไม่ก็ Cocoa.framework (สำหรับ Mac App)

วิธีการก็คือ Target ไหนใช้อะไร Compile บ้างก็ลากใส่เข้าไปตามหมวดหมู่ที่บอกข้างต้นครับ ไม่มีอะไรมาก หรือเวลาที่เรา Add ไฟล์อะไรก็ตามเข้ามาใน Project จะมี Sheet ขึ้นมาถามเราว่า ไฟล์นั้นจะ Copy หรือไม่ จะ link กับ Project อะไรยังไง ก็ให้ลองสังเกตด้านล่างครับ ว่าจะมีถาม Target ไหนด้วย เราก็สามารถเพิ่ม Resource ให้กับแต่ละ Target ผ่านทางนี้ได้เช่นกัน

addtoproj.png

อันนี้เป็นผลพลอยได้ของการสร้าง Target ตั้งแต่แรกๆครับ ส่วนถ้าไม่ได้ทำไว้แต่แรกก็ต้องมาลกาเพิ่มเอาเอง หรืออีกวิธีนึงคือ Duplicate target เอาแล้วค่อยเพิ่ม/ตัดออก เอาก็ยังได้ แต่วิธีนี้ต้อง config อะไรเยอะหน่อยเพื่อไม่ให้มันทับกัน และผมจะไม่ขอพูดถึงในที่นี้นะครับ มันค่อนข้างเยอะ

ต่อไปเป็นวิธีการเลือก Target วิธีการไม่ยากเลย กำหนดเอาที่ปุ่มด้านซ้ายบน กดแล้วจะขึ้น Menu ขึ้นมา ก็เลือก Target ที่ต้องการ build แค่นี้แหละครับ เสร็จแล้ว ง่ายจัง

settarget.png

เราได้ Target ใหม่แล้วสามารถ Config ได้ตามต้องการ คราวนี้เราจะสามารถใช้ source code เดียวกันแต่กำหนดการทำงานให้ต่างกันตาม target ได้หรือไม่ เพราะไม่งั้นการสร้าง target ก็ไม่มีประโยชน์อะไรเท่าไหร่ เพราะต้องเขียน class มากกว่ารอบเดียวขึ้นไปอยู่ดี ? คำตอบคือ “ได้ครับ” วิธีการที่ผมใช้ก็คือ “การตั้ง Tag ให้ Target แล้วเขียน source code กำหนดไปแต่ละ target โดยดูค่าจาก tag นั่นแหละ” (งงมั้ยเนี่ย)

ขั้นตอนก็คือ ไปตั้ง Tag ให้ Target โดยการ Double click ที่ target ที่ต้องการตั้ง tag (ขอเรียกแบบนี้แล้วกัน) ไปที่ Tab build แล้ว search Setting ว่า Other C Flags (อยู่ใน GCC 4.2 Language ครับ) ตั้งค่าเป็น “-DTARGET_NAME=1” ค่าหลังเครื่องหมาย = ก็แล้วแต่จะตั้งนะครับ

targetname.png

จากนั้นในส่วนของ Source code ที่ต้องการให้มีความแตกต่างในแต่ละ Target ก็จะใช้คำสั่ง #if เข้ามาช่วยครับ คำสั่งนี้จะเป็น if ในระดับของการ build เท่านั้น ไม่เกี่ยวกับ application logic ครับ ตัวอย่างการโค้ดก็เป็นแบบนี้

// Implement for each target

#if TARGET_NAME == 1
[aButton setHidden:NO];
[bButton setHidden:NO];
#elif TARGET_NAME == 2
[aButton setHidden:YES];
[bButton setHidden:NO];
#else
[aButton setHidden:YES];
[bButton setHidden:YES];
#endif

จากโค้ดตัวอย่างเป็นการ implement ง่ายๆนะครับ แค่ทำให้ดูว่า คำสั่ง #if, #elif, #endif รูปแบบเป็นไงบ้าง น่าจะพอเห็นภาพนะครับ

สำหรับ Entry นี้ก็คงจะพอแค่นี้นะครับ Entry หลังๆเกี่ยวกับ Target และ iPad ไว้ได้ลองของจริงแล้วจะเอามาแชร์ให้กันอีกนะครับ ตอนนี้ก็ happy coding สวัสดีครับ ;)

Entry filed under: Cocoa Programming, iPhone Programming, Programming, Tips & Techniques. Tags: , , , , , , , , , , .

How to send email from my iPhone app? Why I choose XCode4 Even it still preview ?

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  เปลี่ยนแปลง )

Google photo

You are commenting using your Google account. Log Out /  เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out /  เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out /  เปลี่ยนแปลง )

Connecting to %s

Subscribe to the comments via RSS Feed


del.icio.us For iPhone dev

Post Calendar

เมษายน 2010
พฤ อา
« มี.ค.   ก.ค. »
 1234
567891011
12131415161718
19202122232425
2627282930  

%d bloggers like this: