App Group เป็นกลไกของ iOS ที่สร้างคอนเทนเนอร์ที่ใช้ร่วมกันสำหรับการแลกเปลี่ยนข้อมูลระหว่างแอปและส่วนขยาย หากไม่มีมัน แต่ละกระบวนการ (แอปหลัก วิดเจ็ต ส่วนขยายการแชร์) จะทำงานในแซนด์บ็อกซ์ที่แยกออกจากกันและไม่สามารถเข้าถึงข้อมูลของคอมโพเนนต์ข้างเคียงได้ ตาม Apple Developer Documentation, 2026 App Group แก้ปัญหานี้ด้วยตัวระบุกลุ่มเดียวที่ระบุใน entitlements มันเป็นเครื่องมือพื้นฐานสำหรับการสร้างประสบการณ์ผู้ใช้ที่สอดคล้องกันในระบบนิเวศ iOS
ประเด็นสำคัญ
App Group เป็นกลไกของระบบปฏิบัติการ iOS ที่ให้พื้นที่จัดเก็บที่ใช้ร่วมกันสำหรับหลายกระบวนการจากนักพัฒนาคนเดียวกัน หากไม่มีมัน แต่ละส่วนขยายจะทำงานในแซนด์บ็อกซ์ของตัวเองและไม่สามารถอ่านข้อมูลที่เขียนโดยคอมโพเนนต์อื่นได้ App Group แก้ปัญหาการแยกนี้โดยสร้างไดเรกทอรีบนระบบไฟล์ที่กระบวนการทั้งหมดที่มี entitlements ที่ถูกต้องสามารถเข้าถึงได้
ตัวระบุกลุ่มเริ่มต้นด้วยคำนำหน้า group. และระบุในไฟล์ entitlements ของโปรเจกต์ ใน Xcode ตัวระบุนี้จะถูกเพิ่มผ่าน Capabilities — ระบบจะรวมไว้ในลายเซ็นของแอปโดยอัตโนมัติ หลังจากกำหนดค่าแล้ว สมาชิกกลุ่มทั้งหมดจะสามารถเข้าถึงไดเรกทอรีที่ใช้ร่วมกันที่ Library/Application Support/ ภายในคอนเทนเนอร์
ตาม Apple WWDC 2020 Session 10026 App Group ครอบคลุมสามสถานการณ์หลัก: การซิงค์การตั้งค่าผ่าน NSUserDefaults การแชร์ไฟล์ผ่าน FileManager และ Core Data ที่ใช้ร่วมกันกับที่เก็บเดียว แต่ละสถานการณ์เพียงต้องการระบุตัวระบุกลุ่มใน API ที่เกี่ยวข้อง
iOS สร้างคอนเทนเนอร์ที่ใช้ร่วมกันเมื่อกระบวนการใด ๆ ที่มี entitlement com.apple.security.application-groups เริ่มทำงานครั้งแรก ทางกายภาพ คอนเทนเนอร์อยู่ในไดเรกทอรีของระบบ — เส้นทางของมันแตกต่างจากแซนด์บ็อกซ์ของแอปหลักและส่วนขยาย แต่กระบวนการที่ได้รับอนุญาตทั้งหมดมีสิทธิ์ในการอ่านและเขียน
Apple รับประกัน ความปลอดภัย ของ App Group ผ่านการรวมกันของ team ID และลายเซ็นโค้ด กระบวนการที่ไม่ได้ลงนามด้วยใบรับรองนักพัฒนาคนเดียวกันไม่สามารถเข้าถึงคอนเทนเนอร์กลุ่มได้ ซึ่งป้องกันการรั่วไหลของข้อมูลระหว่างแอปของนักพัฒนาต่างกัน
รูปแบบตัวระบุ: group.<team-id>.<name> ตัวอย่างเช่น group.ABC123DEFG.widget-data สามารถสร้างหลายกลุ่มบนอุปกรณ์เดียว แต่ละกลุ่มมีชุดสมาชิกของตัวเอง แอปเดียวสามารถเป็นสมาชิกของหลาย App Group พร้อมกัน — ซึ่งมีประโยชน์สำหรับการแยกข้อมูลของส่วนขยายต่าง ๆ
// Get the App Group container URL
guard let containerURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.widget")
else { return }
// Create a file in the shared container
let fileURL = containerURL.appendingPathComponent("shared.data")
try "Hello from main app".write(to: fileURL, atomically: true, encoding: .utf8)
FileManager มีเมธอด containerURL(forSecurityApplicationGroupIdentifier:) ที่ส่งคืน URL ของไดเรกทอรีที่ใช้ร่วมกัน สิ่งสำคัญคือต้องเรียกเมธอดนี้แยกกันในแต่ละกระบวนการ — เส้นทางทางกายภาพเหมือนกัน แต่แต่ละกระบวนการมองผ่านมุมมองความปลอดภัยของตัวเอง
การเปิดใช้งาน App Group ใน Xcode เริ่มต้นด้วย Capabilities — สวิตช์ App Groups เพิ่ม entitlement ให้กับโปรเจกต์ Apple Developer Portal ยังกำหนดให้ตัวระบุแอปต้องรวมความสามารถนี้ด้วย หากไม่มี ลายเซ็นโค้ดจะไม่ทำงานบนอุปกรณ์จริง
เปิดโปรเจกต์ของคุณใน Xcode เลือก target ของแอปและไปที่แท็บ Signing & Capabilities คลิก + และเลือก App Groups สร้างกลุ่มใหม่หรือเลือกกลุ่มที่มีอยู่ ทำซ้ำขั้นตอนเดียวกันสำหรับแต่ละส่วนขยายที่ต้องการเข้าถึงคอนเทนเนอร์ที่ใช้ร่วมกัน ผู้เข้าร่วมทั้งหมดต้องใช้ตัวระบุกลุ่มเดียวกัน
หลังจากเปิดใช้งาน Capabilities Xcode จะสร้างไฟล์ .entitlements โดยอัตโนมัติด้วยคีย์ com.apple.security.application-groups และอาร์เรย์ของตัวระบุ ตรวจสอบให้แน่ใจว่าส่วนขยายที่จำเป็นทั้งหมดมีไฟล์นี้ด้วย team ID ที่ถูกต้องในตัวระบุกลุ่ม
<!-- Example entitlements file -->
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.example.shared</string>
</array>
หากโปรเจกต์ของคุณมีหลายส่วนขยาย (Today Widget, Share Extension, Notification Service) แต่ละส่วนต้องมีไฟล์ entitlements ของตัวเองกับกลุ่มเดียวกัน การ ไม่มี entitlements ใน target ใด ๆ เป็นสาเหตุทั่วไปที่ส่วนขยายไม่เห็นข้อมูลที่ใช้ร่วมกัน
วิธีที่ง่ายที่สุดในการซิงค์ข้อมูลระหว่างแอปและส่วนขยายคือ UserDefaults พร้อม suite name แทนที่จะใช้ UserDefaults.standard มาตรฐาน คุณสร้างอินสแตนซ์ด้วยตัวระบุ App Group และกระบวนการทั้งหมดอ่านการตั้งค่าเดียวกัน
ตาม Apple Human Interface Guidelines กลไกนี้เหมาะสำหรับการซิงค์สถานะ: ธีมที่เลือก รายการโปรด แฟล็กการเริ่มต้นใช้งาน อย่างไรก็ตาม มันไม่ได้ออกแบบมาสำหรับข้อมูลปริมาณมากหรือการเขียนพร้อมกัน — สำหรับกรณีนั้นให้ใช้ไฟล์หรือ Core Data
// Write to UserDefaults App Group (main app)
let defaults = UserDefaults(suiteName: "group.com.example.shared")
defaults?.set(true, forKey: "isDarkMode")
defaults?.synchronize()
// Read from UserDefaults App Group (widget extension)
let sharedDefaults = UserDefaults(suiteName: "group.com.example.shared")
let isDark = sharedDefaults?.bool(forKey: "isDarkMode") ?? false
หมายเหตุ: อินสแตนซ์ UserDefaults ที่มี suiteName ถูกสร้างแยกกันในแต่ละกระบวนการแต่อ่านจาก ไฟล์ plist เดียวกันในคอนเทนเนอร์ที่ใช้ร่วมกัน เมธอด synchronize() รับประกันการเขียนลงดิสก์ทันที — ใน iOS 13+ สามารถละเว้นได้เนื่องจากระบบซิงค์ข้อมูลเป็นระยะ
สำหรับสถานการณ์ที่ซับซ้อนมากขึ้น App Group ให้การเข้าถึงระบบไฟล์ที่ใช้ร่วมกัน ไฟล์ใด ๆ ที่สร้างในไดเรกทอรีคอนเทนเนอร์สามารถเข้าถึงได้โดยทุกกระบวนการในกลุ่ม ซึ่งช่วยให้มีฐานข้อมูล Core Data ที่ใช้ร่วมกัน แคชรูปภาพ หรือไฟล์ชั่วคราว
เพื่อใช้ที่เก็บ Core Data ที่ใช้ร่วมกัน ให้สร้าง NSPersistentContainer ด้วย URL ของไฟล์ .sqlite ที่อยู่ในไดเรกทอรี App Group ตรวจสอบให้แน่ใจว่ามีเพียงกระบวนการเดียวเท่านั้นที่เขียนลงฐานข้อมูลในเวลาเดียวกัน — การเขียนพร้อมกันอาจทำให้ข้อมูลเสียหาย สถาปัตยกรรมทั่วไป: แอปหลักเขียน ส่วนขยายอ่าน
// Setup Core Data with App Group container
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "SharedModel")
guard let appGroupURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.shared")
else { return container }
let storeURL = appGroupURL.appendingPathComponent("SharedModel.sqlite")
container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeURL)]
container.loadPersistentStores { _, error in
if let error = error { fatalError(error.localizedDescription) }
}
return container
}()
อีกวิธีหนึ่งคือแคชรูปภาพบนไฟล์ NSCache อยู่ในหน่วยความจำเท่านั้น แต่ผ่าน App Group คุณสามารถบันทึกภาพที่แคชไว้บนดิสก์ในไดเรกทอรีที่ใช้ร่วมกัน ส่วนขยายวิดเจ็ตสามารถเข้าถึงไฟล์เดียวกันและแสดงข้อมูลล่าสุดโดยไม่ต้องดาวน์โหลดเพิ่มเติมจากเครือข่าย
| สถานการณ์ | API ที่แนะนำ | ขนาดข้อมูล |
|---|---|---|
| การตั้งค่าและแฟล็ก | UserDefaults suiteName | สูงสุด 1 KB |
| แคชรูปภาพ | FileManager + NSCache | สูงสุด 100 MB |
| ข้อมูลที่มีโครงสร้าง | ที่เก็บ Core Data | สูงสุด 500 MB |
| ไฟล์ชั่วคราว | FileManager ชั่วคราว | สูงสุด 50 MB |
เมื่อทำงานกับไฟล์ที่ใช้ร่วมกัน โปรดทราบว่าระบบสามารถยุติส่วนขยายได้ทุกเมื่อ ใช้ NSFileCoordinator เพื่อประสานงานการเข้าถึงและหลีกเลี่ยงความเสียหายของข้อมูลเมื่อหลายกระบวนการเขียนพร้อมกัน
คำถามที่พบบ่อย
App Group เป็นกลไกของ iOS ที่สร้างคอนเทนเนอร์ที่ใช้ร่วมกันสำหรับจัดเก็บข้อมูลระหว่างแอปและส่วนขยาย มันช่วยให้กระบวนการที่มีตัวระบุกลุ่มเดียวกันแลกเปลี่ยนไฟล์ การตั้งค่า UserDefaults และข้อมูล Core Data ผ่านไดเรกทอรีเดียวบนระบบไฟล์
เปิด Capabilities ของ target ใน Xcode เปิดใช้งาน App Groups และเพิ่มตัวระบุในรูปแบบ group.* จากนั้นทำซ้ำขั้นตอนเดียวกันสำหรับแต่ละส่วนขยายที่ต้องการเข้าถึงคอนเทนเนอร์ที่ใช้ร่วมกัน ตรวจสอบให้แน่ใจว่าผู้เข้าร่วมทั้งหมดใช้ตัวระบุกลุ่มเดียวกัน
ส่วนขยาย iOS ทุกประเภทรองรับ App Group: Today Widget (ส่วนขยายวิดเจ็ต), Share Extension, Notification Service Extension, Custom Keyboard และอื่น ๆ แต่ละส่วนขยายต้องมีไฟล์ entitlements แยกต่างหากด้วยตัวระบุกลุ่มเดียวกับแอปหลัก
ได้ แต่เฉพาะเมื่อแอปลงนามด้วยใบรับรองนักพัฒนาคนเดียวกันและมี team ID เดียวกัน Apple รับประกันความปลอดภัยผ่านลายเซ็นโค้ด: สองแอปจากนักพัฒนาต่างกันไม่สามารถเข้าถึงคอนเทนเนอร์เดียวกันได้แม้จะมีตัวระบุกลุ่มเหมือนกัน
ใช้ UserDefaults พร้อม suite name สำหรับการตั้งค่าเล็กน้อย FileManager สำหรับไฟล์ และ Core Data สำหรับข้อมูลที่มีโครงสร้าง API เหล่านี้ทั้งหมดทำงานกับไดเรกทอรี App Group — เพียงระบุตัวระบุกลุ่มเมื่อเริ่มต้น สำหรับ Core Data ตรวจสอบให้แน่ใจว่า URL ของที่เก็บชี้ไปยังไดเรกทอรีที่ใช้ร่วมกัน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม