On-Demand Resources คือเทคโนโลยีของ Apple สำหรับการโหลดเนื้อหาแอปพลิเคชันแบบล่าช้า แทนที่จะรวมทรัพยากรทั้งหมดในแพ็คเกจติดตั้ง นักพัฒนาจะโฮสต์ไว้บนเซิร์ฟเวอร์ App Store และขอตามความจำเป็น ตาม Apple ODR Guide วิธีนี้ช่วยลดขนาดการติดตั้งเริ่มต้นและอนุญาตให้เพิ่มเนื้อหาใหม่โดยไม่ต้องอัปเดตเวอร์ชันแอป
ประเด็นสำคัญ
On-Demand Resources (ODR) คือระบบจัดการเนื้อหาที่รวมอยู่ใน iOS, tvOS และ macOS ช่วยให้นักพัฒนาสามารถแบ่งทรัพยากรแอปเป็นแบบบังคับ (รวมในแพ็คเกจติดตั้ง) และตามความต้องการ (เก็บใน App Store และดาวน์โหลดเมื่อจำเป็น)
ระบบ ODR ทำงานกับสามเอนทิตีหลัก: แท็ก แพ็คเกจทรัพยากร และ คำขอ แท็กคือตัวระบุสตริงที่รวบรวมกลุ่มไฟล์ แพ็คเกจทรัพยากรคือชุดข้อมูลที่เชื่อมโยงกับแท็ก คำขอคือการเรียกโปรแกรมไปยัง NSBundleResourceRequest ที่เริ่มต้นการโหลดแพ็คเกจ
การโหลดทรัพยากร ผ่านหลายขั้นตอน: การเริ่มต้นคำขอด้วยแท็กที่ระบุ การตรวจสอบความพร้อมในพื้นที่จัดเก็บในเครื่อง การดาวน์โหลดจากเซิร์ฟเวอร์ Apple หากไม่มี การแจ้งให้แอปทราบเมื่อพร้อม และการปล่อยทรัพยากรหลังการใช้งาน ระบบจะจัดการแคชและการลบทรัพยากรที่ไม่ได้ใช้โดยอัตโนมัติ
| ขั้นตอน | การทำงานของระบบ | เวลาดำเนินการ |
|---|---|---|
| การเริ่มต้น | สร้าง NSBundleResourceRequest พร้อมแท็ก | ทันที |
| ตรวจสอบแคช | ค้นหาทรัพยากรในพื้นที่จัดเก็บในเครื่อง | 0.1–0.5 วินาที |
| ดาวน์โหลด | ดาวน์โหลดจาก CDN ของ Apple | ขึ้นอยู่กับขนาด |
| แจ้งเตือน | เรียก completion handler หรือตัวแทน | ทันที |
| ปล่อย | ทำเครื่องหมายทรัพยากรว่าระบบสามารถลบได้ | ตามคำขอ iOS |
กลไก ODR อาศัยบริการเบื้องหลังที่จัดการคำขอทรัพยากรจากพื้นที่จัดเก็บคลาวด์ของ App Store เมื่อแอปขอแท็ก ระบบจะตรวจสอบว่าทรัพยากรมีอยู่ในแคชในเครื่องหรือไม่ หากไม่มี — ระบบจะเริ่มดาวน์โหลดผ่านเซสชัน URL เบื้องหลังที่รองรับการ resumed สำหรับการเชื่อมต่อที่ถูกขัดจังหวะ
import Foundation
class ResourceManager {
let odrRequest = NSBundleResourceRequest(tags: ["level-3"])
func loadLevel3() {
odrRequest.conditionallyBeginAccessingResources { available in
if available {
self.startLevel3()
} else {
self.odrRequest.beginAccessingResources { error in
guard error == nil else { return }
self.startLevel3()
}
}
}
}
func releaseResources() {
odrRequest.endAccessingResources()
}
}
เมธอด conditionallyBeginAccessingResources ตรวจสอบความพร้อมของทรัพยากรในแคชโดยไม่โหลดทันที หากแฟล็กความพร้อมเป็นบวก — แอปจะดำเนินการต่อโดยไม่ชักช้า หากทรัพยากรไม่อยู่ beginAccessingResources จะเริ่มดาวน์โหลดพร้อมตัวบ่งชี้ความคืบหน้าผ่านคุณสมบัติ progress
iOS จัดการลำดับความสำคัญในการโหลดทรัพยากร ODR ตามกิจกรรมปัจจุบันของแอป เมื่อแอปอยู่เบื้องหน้า การโหลดจะดำเนินการด้วยลำดับความสำคัญสูง ในเบื้องหลัง iOS อาจเลื่อนการโหลดหรือหยุดชั่วคราวเมื่อแบตเตอรี่ต่ำ
ทรัพยากร ODR สามารถรวมรูปภาพ วิดีโอ ไฟล์เสียง สไปรต์ ข้อมูลเลเวล และไฟล์อื่น ๆ ที่ไม่สำคัญต่อการเปิดแอป ทรัพยากรแต่ละรายการจะเชื่อมโยงกับแท็กหนึ่งรายการขึ้นไปที่กำหนดความเป็นสมาชิกบล็อกฟังก์ชัน
ใน Xcode แท็กจะถูกกำหนดค่าผ่านตัวตรวจสอบ Resource Tags ในแท็บ Target Membership นักพัฒนาระบุสำหรับแต่ละไฟล์ในโครงการว่าไฟล์นั้นรวมอยู่ในบันเดิลหลักหรือโหลดโดยแท็ก ไฟล์หนึ่งสามารถเป็นสมาชิกของหลายแท็ก ซึ่งช่วยให้สามารถนำทรัพยากรกลับมาใช้ใหม่ในส่วนต่าง ๆ ของแอป
<!-- ตัวอย่างการกำหนดค่า Resource Tags ใน Info.plist -->
<key>NSBundleResourceRequestTags</key>
<dict>
<key>level-3</key>
<array>
<string>levels/level3.scnassets</string>
<string>textures/level3_tex.png</string>
</array>
</dict>
Apple แยกแยะสามหมวดหมู่ของ แท็ก ODR ตามระยะเวลาที่ทรัพยากรควรอยู่บนอุปกรณ์ แท็กติดตั้งเริ่มต้นจะโหลดพร้อมกับแอปและจะไม่ถูกลบโดยระบบ ลำดับแท็ก Prefetch กำหนดลำดับการโหลดล่วงหน้าเบื้องหลังทันทีหลังการติดตั้ง แท็กหลักจะถูกขอตามความต้องการและอาจถูกลบโดย iOS เมื่อพื้นที่จัดเก็บไม่เพียงพอ
นอกจากหมวดหมู่แล้ว แต่ละแท็กสามารถมีลำดับความสำคัญในการดาวน์โหลด แท็กที่มี ลำดับความสำคัญสูง จะถูกโหลดก่อนแท็กที่มีลำดับความสำคัญต่ำ แม้ว่าจะถูกขอทีหลังก็ตาม ช่วยให้นักพัฒนาควบคุมลำดับการปรากฏของเนื้อหา: ทรัพยากรสำคัญสำหรับหน้าจอหลักก่อน จากนั้นวัสดุเพิ่มเติมสำหรับส่วนลึกของแอป
การตั้งค่า ODR ใน Xcode รวมสามขั้นตอน: การจัดหมวดหมู่ทรัพยากรตามแท็ก การกำหนดค่าพารามิเตอร์การดาวน์โหลดใน Info.plist และการดำเนินการขอโดยโปรแกรมผ่าน NSBundleResourceRequest งานส่วนใหญ่ทำในฝั่งบิลด์
// การตรวจสอบสถานะและการติดตามความคืบหน้า ODR
func monitorODRProgress(tag: String) {
let request = NSBundleResourceRequest(tags: [tag])
let observer = request.progress.observe(\.fractionCompleted) { progress, _ in
DispatchQueue.main.async {
let percent = Int(progress.fractionCompleted * 100)
print("ODR: \(percent)% โหลดแล้ว")
}
}
}
ความคืบหน้าการดาวน์โหลด ถูกติดตามผ่านคุณสมบัติ progress ของคลาส NSProgress ที่รองรับการสังเกต KVO แอปสามารถแสดงตัวบ่งชี้การโหลดให้ผู้ใช้เห็นระหว่างการดาวน์โหลดทรัพยากร หลังจากดาวน์โหลดเสร็จ ทรัพยากรจะพร้อมใช้งานในบันเดิลหลักของแอปผ่านกลไก FileManager และ NSDataAsset มาตรฐาน
โควต้า ODR ขึ้นอยู่กับเวอร์ชัน iOS เริ่มจาก iOS 13 อุปกรณ์สามารถจัดเก็บทรัพยากรตามความต้องการได้สูงสุด 20 GB ต่อบัญชี พื้นที่นี้ถูกใช้ร่วมกันระหว่างแอปทั้งหมดที่ติดตั้งบนอุปกรณ์ — หากแอปหนึ่งใช้พื้นที่มาก แอปอื่นก็จะเหลือน้อยลง
การตรวจสอบพื้นที่ที่ใช้ ดำเนินการผ่าน NSBundleResourceRequest แอปสามารถตรวจสอบพื้นที่จัดเก็บ ODR ที่มีอยู่และตัดสินใจตามนั้นว่าควรโหลดทรัพยากรใดก่อน ขอแนะนำให้ใช้กลไกสำรอง: หากพื้นที่จัดเก็บ ODR เต็ม ให้ใช้ทรัพยากรคุณภาพลดลงจากบันเดิลหลัก
เมื่อเกินโควต้า ระบบจะลบทรัพยากรที่ติดแท็กตามความต้องการตามลำดับที่ไม่ได้ใช้งานนานที่สุด เริ่มจากที่เก่าที่สุด ตัวจัดการทรัพยากรในโค้ดแอปสามารถติดตามการใช้พื้นที่จัดเก็บ ODR ปัจจุบันผ่านคุณสมบัติ NSBundleResourceRequestนักพัฒนาต้องพิจารณาว่า iOS อาจตัดสินใจลบทรัพยากรตามความต้องการได้ตลอดเวลา — แอปต้องจัดการสถานการณ์ที่ทรัพยากรที่โหลดไว้ก่อนหน้านี้ suddenly ไม่พร้อมใช้งานอย่างถูกต้อง ขอแนะนำให้ดักจับข้อผิดพลาดการเข้าถึงทรัพยากรและขอใหม่ผ่าน beginAccessingResources สำหรับทรัพยากรที่สำคัญซึ่งแอปไม่สามารถทำงานได้หากไม่มี ให้ใช้แท็กติดตั้งเริ่มต้นที่ระบบไม่ลบ
On-Demand Resources มอบเครื่องมือที่ยืดหยุ่นให้นักพัฒนาในการจัดการขนาดแอป แต่กำหนดข้อจำกัดหลายประการเกี่ยวกับความพร้อมของเครือข่ายและนโยบายพื้นที่จัดเก็บของ iOS
ข้อดีหลักของ ODR คือการลดขนาดการติดตั้งเริ่มต้นอย่างมาก เกมที่มีหลายเลเวล แอปที่มีเนื้อหาวิดีโอ หรือชุดรูปภาพขนาดใหญ่สามารถโหลดเนื้อหาเป็นส่วน ๆ ผู้ใช้สามารถเข้าถึงฟังก์ชันพื้นฐานได้ทันที ในขณะที่ทรัพยากรเพิ่มเติมถูกดาวน์โหลดในเบื้องหลัง
ODR ต้องการการเชื่อมต่ออินเทอร์เน็ตอย่างต่อเนื่องเพื่อโหลดทรัพยากรในการเข้าถึงครั้งแรก ผู้ใช้ในพื้นที่ที่มีสัญญาณอ่อนอาจพบความล่าช้าและข้อผิดพลาดในการดาวน์โหลด นอกจากนี้ Apple ไม่รับประกันว่าทรัพยากรที่ดาวน์โหลดจะยังคงอยู่ในอุปกรณ์ — เมื่อพื้นที่จัดเก็บไม่เพียงพอ iOS อาจลบแท็กตามความต้องการโดยไม่แจ้งเตือน
คำถามที่พบบ่อย
ODR อนุญาตให้เพิ่มและแก้ไขทรัพยากรโดยไม่ต้องเผยแพร่เวอร์ชันใหม่ใน App Store เพียงอัปเดตไฟล์บนเซิร์ฟเวอร์ Apple ผ่าน Xcode และกำหนดให้กับแท็กเดียวกัน ในการขอครั้งถัดไป แอปจะได้รับเวอร์ชันล่าสุดของทรัพยากร สะดวกสำหรับเนื้อหาตามฤดูกาล โปรโมชั่นชั่วคราว และการทดสอบ A/B ของรูปภาพและเลย์เอาต์ใหม่
ระบบ จะลบทรัพยากรที่ติดแท็กตามความต้องการเมื่อต้องการเพิ่มพื้นที่ให้แอปอื่น ทรัพยากรแท็กติดตั้งเริ่มต้นจะไม่ถูกลบ ลำดับการลบถูกกำหนดโดยอัลกอริทึม LRU (Least Recently Used) — ทรัพยากรที่ไม่ได้เข้าถึงนานที่สุดจะถูกลบก่อน
ตั้งแต่ iOS 13 ขีดจำกัดพื้นที่จัดเก็บ ODR ทั้งหมดคือ 20 GB ต่อผู้ใช้ Apple ID ขนาดของแท็กเดียวไม่ควรเกิน 512 MB เพื่อประสิทธิภาพการดาวน์โหลดที่ดีที่สุด เมื่อเกินขีดจำกัด คำขอจะล้มเหลวด้วย NSBundleResourceRequestLowDiskSpaceError
ใช่ หลังจากดาวน์โหลด ทรัพยากรจะถูกบันทึกในแคชในเครื่องและพร้อมใช้งานใน โหมดออฟไลน์ โดยไม่ต้องเชื่อมต่ออินเทอร์เน็ต ปัญหาเกิดขึ้นเมื่อ iOS ลบทรัพยากรเนื่องจากพื้นที่จัดเก็บไม่เพียงพอและผู้ใช้พยายามเข้าถึงโดยไม่มีเครือข่าย
ODR ถูกรวมเข้ากับโครงสร้างพื้นฐานของ App Store: ทรัพยากรถูกโฮสต์บน CDN ของ Apple จัดการโดยระบบแคช และไม่ต้องการให้นักพัฒนาตั้งค่าเซิร์ฟเวอร์ของตนเอง URLSession ต้องการโครงสร้างพื้นฐานเซิร์ฟเวอร์ การควบคุมเวอร์ชัน และการจัดการแคชด้วยตนเอง ODR ยังจัดการการดาวน์โหลดต่อโดยอัตโนมัติเมื่อการเชื่อมต่อถูกขัดจังหวะ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม