วิธีกำหนดโค้ดสำหรับ iOS เวอร์ชันต่างๆ

ฉันกำลังทำงานกับแอป iOS ฉันอยากให้มันรองรับ iOS 7 และ 8 มันไปได้สวยทีเดียว แต่ก็มีส่วนต่างๆ มากมายในแอปที่ใช้ Apple API API เหล่านี้บางส่วนทำงานได้ทั้งใน iOS 8 และ 7 อย่างไรก็ตาม API บางส่วนเลิกใช้งานแล้วใน iOS 8 ดังนั้นฉันจึงไปที่ไซต์นักพัฒนาซอฟต์แวร์ของ Apple เพื่อดูว่าจะแทนที่ด้วยอะไร (วิธีการใหม่/ฯลฯ....)

อย่างไรก็ตาม ตอนนี้ฉันมีปัญหาว่าแอปจะทำงานบน iOS 8 ได้ดี แต่บางส่วนกลับไม่ทำงานอย่างถูกต้องบน iOS 7 เนื่องจากฉันพยายามใช้ iOS 8 API...... (555) .

ฉันแค่อยากจะรู้ว่าอะไรคือวิธีที่ดีที่สุดในการใช้โค้ดซึ่งใช้งานได้กับ iOS 8 และ 7 ฉันมีไอเดียเล็กๆ น้อยๆ (ด้านล่าง) แต่ฉันไม่แน่ใจว่าวิธีไหนดีที่สุด:

ไอเดีย 1

เมื่อใดก็ตามที่ฉันมีโค้ดที่ใช้ไม่ได้กับทั้งสองระบบปฏิบัติการ ฉันจะใช้ฟังก์ชัน if (ซึ่งเรียกมาโคร) ดังนี้:

if (SYSTEM_VERSION_LESS_THAN(@"8.0")) {
    // iOS 7 device. Use iOS 7 apis.
}

else {
   // iOS 8 (or higher) - use iOS 8 apis.
}

ไอเดีย 2

ฉันกำลังคิดที่จะใช้คำจำกัดความ ifdef ทั่วทั้งแอปดังนี้:

#ifdef __IPHONE_8_0
     // iOS 8 code here....
#else
     // iOS 7 code here....
#endif

วิธีไหนดีกว่ากัน? ฉันคิดว่าแนวคิดที่สองเร็วกว่ามากและใช้ทรัพยากรน้อยกว่าใช่ไหม

หรือความคิดของฉันทั้งคู่เป็นขยะ? มีวิธีที่ดีกว่ามากในการแก้ปัญหานี้หรือไม่?

ขอบคุณสำหรับเวลาของคุณแดน


person Supertecnoboff    schedule 10.01.2015    source แหล่งที่มา
comment
อย่าทดสอบเวอร์ชัน iOS ทดสอบความพร้อมใช้งานของ API ณ รันไทม์ อ่านคู่มือความเข้ากันได้ของ SDK ในเอกสาร   -  person rmaddy    schedule 10.01.2015
comment
โปรดทราบ - หาก API รองรับใน iOS 7 และเลิกใช้งานแล้วใน iOS 8 คุณไม่จำเป็นต้องดำเนินการใดๆ เลย iOS 7 API คือสิ่งที่คุณควรใช้ มันจะยังคงทำงานภายใต้ iOS 8   -  person rmaddy    schedule 10.01.2015
comment
@rmaddy คุณแน่ใจเกี่ยวกับเรื่องนั้น ฉันกำลังทำงานกับการอ่านไฟล์ XML Plist แบบธรรมดา ใน iOS 8 รหัสของฉันที่ใช้ในการอ่านไฟล์ XML หยุดทำงาน ทันทีที่ฉันทดสอบด้วย iOS 8 api มันก็เริ่มทำงานได้อีกครั้งตามปกติ นอกจากนี้ ยังบอกด้วยว่าเราควรยึดติดกับ API ที่เลิกใช้แล้ว..... ซึ่งฟังดูอันตราย อาจทำให้หน่วยความจำรั่วหรือล่มโดยไม่คาดคิดได้อย่างแน่นอน   -  person Supertecnoboff    schedule 10.01.2015
comment
ฉันมั่นใจ 100% เกี่ยวกับเรื่องนั้น หากคุณประสบปัญหากับ API ใดโดยเฉพาะ ให้โพสต์คำถามเกี่ยวกับปัญหานั้นโดยเฉพาะ คำถามนี้กว้างเกินไปที่จะให้รายละเอียดเฉพาะเจาะจงเล็กน้อย   -  person rmaddy    schedule 10.01.2015
comment
API ที่เลิกใช้แล้วไม่ได้หมายความว่าคุณไม่ควรใช้สิ่งนั้นในเวอร์ชันปัจจุบัน หมายความว่า มันจะใช้งานไม่ได้ตั้งแต่เวอร์ชันถัดไปเป็นต้นไป และใช้งานได้จนถึงเวอร์ชันปัจจุบันเท่านั้น   -  person Midhun MP    schedule 10.01.2015
comment
@MidhunMP โอเคครับ ขอบคุณสำหรับคำอธิบาย มีประโยชน์จริงๆ   -  person Supertecnoboff    schedule 10.01.2015
comment
@MidhunMP API ที่เลิกใช้ไม่ได้หมายความว่าหยุดทำงาน API ที่เลิกใช้งานแล้วใน iOS 3 ยังคงใช้งานได้โดยมีข้อยกเว้นที่ไม่ค่อยเกิดขึ้น ใช่ หมายความว่าคุณไม่ควรใช้เวอร์ชันนี้ในเวอร์ชันที่เลิกใช้งานแล้ว เว้นแต่คุณจะยังรองรับเวอร์ชันก่อนการเลิกใช้งานด้วย กล่าวอีกนัยหนึ่ง การเลิกใช้งานใน iOS 8 หมายความว่าหากคุณรองรับเฉพาะ iOS 8 คุณควรย้ายไปที่ API ใหม่ทันที แต่ถ้าคุณรองรับ iOS 7 ด้วย คุณก็สามารถใช้ API ที่เลิกใช้แล้วต่อไปได้   -  person rmaddy    schedule 10.01.2015


คำตอบ (2)


ฉันไม่แนะนำให้ตรวจสอบเวอร์ชันและเขียนโค้ดตามนั้น แต่คุณต้องตรวจสอบว่า API นั้นพร้อมใช้งานหรือไม่

สำหรับการตรวจสอบชั้นเรียนที่มีอยู่หรือไม่:

Class checkClass = NSClassFromString(@"CheckingClass");

if (checkClass)
{
   // Available
}
else
{
  // Not Available
}

หากคุณต้องการตรวจสอบคุณสมบัติ/ฟังก์ชั่นที่ใช้งานได้

if ([checkClass respondsToSelector:@selector(yourMethod:)])
{
   // Feature/ Method Available
}
else
{
   // Feature/ Method Not Available
}

หมายเหตุ:

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

person Midhun MP    schedule 10.01.2015
comment
โอเค ขอบคุณสำหรับคำตอบและตัวอย่างของคุณ ดูเหมือนว่านี่เป็นวิธีที่ดีที่สุดในการแก้ไขปัญหา ขอบคุณอีกครั้ง. - person Supertecnoboff; 10.01.2015
comment
หมายเหตุที่อยู่ท้ายคำตอบนี้ไม่ถูกต้อง API ที่เลิกใช้แล้วแทบไม่เคยหยุดทำงานเลย - person rmaddy; 10.01.2015
comment
@rmaddy: ฉันไม่เข้าใจสิ่งที่คุณหมายถึง ฉันรู้ว่า API ที่เลิกใช้แล้วจำนวนมากใน iOS 6 ซึ่งใช้ไม่ได้กับ iOS 8 - person Midhun MP; 10.01.2015
comment
ฉันอาจจะพูดเกินจริงไปหน่อย ขึ้นอยู่กับคลาสและ API ฉันรู้จัก API ที่เลิกใช้งานแล้วใน iOS 3.0 ซึ่งยังคงใช้งานได้ใน iOS 8 แต่คุณพูดถูก มี API บางส่วนที่เลิกใช้งานแล้วซึ่งหยุดทำงานอย่างรวดเร็ว แต่นั่นไม่ได้เป็นเช่นนั้นเสมอไป - person rmaddy; 10.01.2015
comment
@rmaddy: ใช่คุณพูดถูก คุณสามารถใช้ API ที่เลิกใช้แล้วได้ตราบใดที่ยังมีอยู่ (ไม่มีอุปสรรคด้านเวอร์ชัน) - person Midhun MP; 10.01.2015
comment
@rmaddy แต่ยังคงเป็น API ที่เลิกใช้แล้วด้วยเหตุผล หากเลิกใช้แล้วแสดงว่าคุณไม่ตั้งใจจะใช้มัน คุณต้องใช้ API ที่ให้มาสำหรับระบบปฏิบัติการเวอร์ชันนั้น ๆ ไม่อย่างนั้นจะมีประโยชน์อะไรในการเลิกสนใจสิ่งใดตั้งแต่แรก...? - person Supertecnoboff; 10.01.2015
comment
@Supertecnoboff Deprecated หมายความว่าการสนับสนุนอาจลดลงในอนาคตในที่สุดอาจจะ ไม่ได้หมายความว่าคุณไม่สามารถใช้มันต่อไปได้ในขณะนี้ หากคุณรองรับ iOS 7 และ 8 ก็ไม่มีอะไรผิดปกติในการใช้ API ที่ใช้งานอยู่ใน iOS 7 แต่เลิกใช้งานแล้วใน iOS 8 ฉันมีแอป App Store ที่เต็มไปด้วยโค้ดดังกล่าว เมื่อฉันยกเลิกการรองรับ iOS 7 ในอนาคต ฉันจะแทนที่ API ที่เลิกใช้แล้วเหล่านั้น - person rmaddy; 10.01.2015

ifdef-way จะไม่ทำงาน เนื่องจากคำสั่งตัวประมวลผลล่วงหน้าได้รับการประเมิน ณ เวลาคอมไพล์ แต่เฉพาะตอนรันไทม์เท่านั้นที่เรารู้ว่าเราต้องจัดการกับ iOS เวอร์ชันใด

คุณจะใช้มาโครเช่นถ้าคุณต้องการรองรับ Mac OS X และ iOS ด้วยโค้ดเดียวกัน เพราะคุณรู้ในขณะคอมไพล์ว่าไบนารี่จะใช้สำหรับ Mac OS หรือ iOS

ดังนั้นในกรณีนี้คุณต้องใช้แนวทางที่ 1 - หรือดีกว่านั้น คุณควรใช้ respondsToSelector: เพื่อตรวจสอบความพร้อมใช้งานแทนการทดสอบเวอร์ชัน iOS หากเป็นไปได้

อย่างไรก็ตาม เนื่องจากคุณกำลังจัดการกับคำเตือนการเลิกใช้งานเท่านั้น คุณไม่จำเป็นต้องดำเนินการใดๆ และควรใช้ API ที่เลิกใช้งานต่อไปจนกว่าแอปจะไม่จำเป็นต้องรองรับ iOS7 อีกต่อไป

person stefreak    schedule 10.01.2015
comment
ขอบคุณสำหรับคำตอบ. ฟังดูดี แต่ฉันคิดว่าฉันจะไปกับคำตอบของ @MidhunMP เนื่องจากการใช้ API ที่เลิกใช้งานแล้ว ไม่ได้ทำให้ฉันมั่นใจว่าแอปของฉันจะทำงานได้โดยไม่ขัดข้อง - person Supertecnoboff; 10.01.2015
comment
การเลิกใช้งานเป็นเพียงการประกาศว่า Apple จะลบออกในอนาคต (ios9) - ไม่ได้หมายความว่ามันไม่เสถียรหรือไม่รองรับอีกต่อไป! - person stefreak; 10.01.2015