Share Extension คือส่วนขยาย iOS ที่เพิ่มแอปของคุณลงในเมนูแชร์ของระบบ ผู้ใช้สามารถส่งเนื้อหาจาก Safari, รูปภาพ, ไฟล์ หรือแอปอื่น ๆ ไปยังแอปของคุณได้โดยตรง — โดยไม่ต้องคัดลอกและสลับระหว่างหน้าต่าง ตามข้อมูลจาก Apple (2024) แอปที่มี Share Extension ได้รับเนื้อหาจากผู้ใช้ มากกว่า 35% เมื่อเทียบกับแอปที่ไม่มีฟังก์ชันการแชร์ ส่วนขยายจะประมวลผลข้อความ รูปภาพ วิดีโอ URL และไฟล์ผ่านอินเทอร์เฟซ NSExtensionItem แบบรวม
ประเด็นสำคัญ
Share Extension คือประเภทของส่วนขยายแอป iOS ที่ปรากฏในเมนูแชร์ของระบบเมื่อเลือกเนื้อหาในแอปใด ๆ ผู้ใช้ไฮไลต์ข้อความใน Safari กดแชร์และเห็นแอปของคุณในรายการการทำงานที่มีให้เลือก หลังจากเลือกแล้ว เนื้อหาจะถูกส่งไปยังส่วนขยายเพื่อประมวลผล: บันทึก เผยแพร่ ส่ง หรือแปลง
แตกต่างจาก Action Extension ตรงที่ Share Extension เชี่ยวชาญด้าน การรับเนื้อหา จากแอปภายนอก ส่วน Action Extension จะส่งข้อมูลจากแอปของคุณออกไปภายนอก Share Extension คือจุดเข้าของเนื้อหาผู้ใช้ ซึ่งเป็นองค์ประกอบสำคัญในการดึงดูดผู้ใช้: ผู้ใช้ทดลองใช้แอปของคุณผ่าน Share Extension โดยไม่ต้องติดตั้งทั้งหมด App Store ห้ามแอปที่มีฟังก์ชันเดียวคือแสดงโฆษณาผ่าน Share Extension (App Store Review Guideline 4.2)
Share Extension ช่วยลดอุปสรรคในการเข้าใช้งาน: ผู้ใช้ส่งเนื้อหามาที่แอปของคุณจากบริบทที่คุ้นเคย — เบราว์เซอร์, แกลเลอรี, ตัวจัดการไฟล์ ตามข้อมูลจาก Branch (2024) แอปที่มี Share Extension แสดง อัตราการคงอยู่สูงกว่า 28% ในวันที่ 7 ผลกระทบเพิ่มเติมคือการแพร่กระจาย: ทุกครั้งที่ผู้ใช้เห็นแอปของคุณในชีตแชร์ จะเกิดการสร้างแบรนด์แบบพาสซีฟโดยไม่มีค่าใช้จ่ายโฆษณา
กลไกของ Share Extension อาศัยการถ่ายโอนเนื้อหาผ่านคอนเทนเนอร์ NSExtensionItem ของระบบ แอปโฮสต์ (Safari, รูปภาพ) จะบรรจุเนื้อหาที่เลือกลงใน NSExtensionItem พร้อมกับประเภทที่ระบุ (public.image, public.url, public.plain-text) ระบบจะส่งคอนเทนเนอร์นี้ไปยังส่วนขยาย ซึ่งจะแยกข้อมูลผ่าน extensionContext.inputItems
Share Extension ทำงานในกระบวนการแยกต่างหากโดยมีเวลาดำเนินการจำกัด — ประมาณ 30 วินาทีสำหรับการประมวลผล ส่วนขยายไม่ควรดำเนินการแบบซิงโครนัสที่ยาวนาน สำหรับการอัปโหลดไฟล์ขนาดใหญ่ ให้ใช้ NSURLSession พร้อมการกำหนดค่าพื้นหลัง SLComposeServiceViewController เป็นคลาสพื้นฐานสำหรับ Share Extension พร้อมการแสดงตัวอย่างเนื้อหาและปุ่มส่ง
iOS ใช้ Uniform Type Identifiers (UTI) เพื่อกำหนดประเภทของเนื้อหาที่กำลังถ่ายโอน UTI หลักสำหรับ Share Extension: public.image (รูปภาพ, ภาพหน้าจอ), public.url (ลิงก์), public.plain-text (ข้อความ), public.video (ไฟล์วิดีโอ) และ public.file-url (ไฟล์) ส่วนขยายจะลงทะเบียน UTI ที่รองรับใน Info.plist ผ่านคีย์ NSExtensionActivationRule
Share Extension ประกอบด้วยสามองค์ประกอบ: เป้าหมายใน Xcode, SLComposeServiceViewController และการกำหนดค่า Info.plist สถาปัตยกรรม กำหนดว่าประเภทเนื้อหาใดจะถูกประมวลผล อินเทอร์เฟซแสดงผลอย่างไร และข้อมูลถูกบันทึกที่ไหน
| องค์ประกอบ | วัตถุประสงค์ | คุณลักษณะ |
|---|---|---|
| Target | เป้าหมายส่วนขยายใน Xcode | บันเดิลแยกต่างหากพร้อมตัวระบุ |
| ViewController | อินเทอร์เฟซและตรรกะการประมวลผล | SLComposeServiceViewController หรือแบบกำหนดเอง |
| Info.plist | การกำหนดค่าการเปิดใช้งานและ UTI | NSExtensionActivationRule พร้อมเพรดิเคต |
| App Groups | พื้นที่จัดเก็บร่วมกับแอป | ชุด UserDefaults สำหรับการถ่ายโอนข้อมูล |
องค์ประกอบสำคัญของการกำหนดค่า Share Extension คือกฎการเปิดใช้งาน กฎจะกำหนดเงื่อนไขที่ส่วนขยายจะปรากฏในชีตแชร์ กฎถูกตั้งค่าใน Info.plist เป็นพจนานุกรมพร้อมข้อจำกัด: จำนวนรูปภาพสูงสุด ความยาวข้อความขั้นต่ำ การมี URL ที่จำเป็น กฎมาตรฐาน จะเปิดใช้งานส่วนขยายสำหรับประเภทเนื้อหาใดประเภทหนึ่ง
// Info.plist — NSExtensionActivationRule สำหรับ Share Extension
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
<integer>5</integer>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
มาดูตัวอย่างการสร้าง Share Extension ใน Swift สำหรับแอปบุ๊กมาร์กกัน ส่วนขยายจะรับ URL จาก Safari แสดงอินเทอร์เฟซตัวอย่าง และบันทึกลิงก์ใน App Group SLComposeServiceViewController มีอินเทอร์เฟซผู้ใช้ที่พร้อมใช้งานพร้อมช่องข้อความและปุ่มเผยแพร่
import Social
import MobileCoreServices
class ShareViewController: SLComposeServiceViewController {
override func isContentValid() -> Bool {
return !(contentText?.isEmpty() ?? true)
}
override func didSelectPost() {
guard let item = extensionContext?.inputItems.first as? NSExtensionItem
else { return }
for attachment in item.attachments ?? [] {
attachment.loadItem(forTypeIdentifier: kUTTypeURL as String) {
[weak self] (item, error) in
if let url = item as? URL {
BookmarkService().save(url, title: self?.contentText)
}
self?.extensionContext?.completeRequest(
returningItems: [], completionHandler: nil)
}
}
}
}
หลังจากส่งเนื้อหา ส่วนขยายจะสิ้นสุดโดยเรียก completeRequest — นี่เป็นขั้นตอนบังคับ หากไม่มี ระบบจะไม่ปล่อยกระบวนการของส่วนขยาย สำคัญ: Share Extension ทำงานในสภาพแวดล้อมที่จำกัดด้วยการเข้าถึงเครือข่ายและระบบไฟล์ที่ถูกจำกัด — ใช้เซสชันพื้นหลังสำหรับการอัปโหลดเนื้อหา
Share Extension ต้องจัดการกับข้อมูลนำเข้าประเภทต่าง ๆ อย่างถูกต้อง: ข้อความ รูปภาพ วิดีโอ URL และไฟล์ แต่ละประเภทใช้ UTI และวิธีการแยกข้อมูลของตนเอง การจัดการแบบสากล — โดยการวนซ้ำผ่าน attachment.attachments พร้อมการตรวจสอบ hasItemConformingToTypeIdentifier
รูปภาพจะถูกส่งเป็น public.image โดยสามารถดึงข้อมูลผ่าน UIImage หรือ Data สำหรับรูปภาพขนาดใหญ่ ให้ใช้ jpegData(compressionQuality:) ก่อนบันทึก Share Extension ไม่ควรแก้ไขรูปภาพต้นฉบับโดยไม่ได้รับอนุญาตอย่างชัดแจ้งจากผู้ใช้ แนะนำให้บันทึกต้นฉบับใน App Group และสร้างตัวอย่างสำหรับแสดงในอินเทอร์เฟซ
Safari และเบราว์เซอร์อื่น ๆ ส่ง URL เป็น public.url และข้อความที่เลือกเป็น public.plain-text NSExtensionItem หนึ่งรายการสามารถมีทั้งสองประเภทพร้อมกัน — URL ของหน้าและข้อความที่เลือกบนหน้านั้น Share Extension ควรตรวจสอบไฟล์แนบทั้งหมดและแยกข้อมูลที่เกี่ยวข้อง สถานการณ์แบบรวม: บันทึก URL เป็นบุ๊กมาร์กและข้อความเป็นบันทึกที่แนบมากับบุ๊กมาร์ก
Share Extension และแอปหลักทำงานในกระบวนการที่แตกต่างกันและไม่มีการเข้าถึงระบบไฟล์ร่วมกัน การแลกเปลี่ยนข้อมูลใช้กลไก App Groups: คอนเทนเนอร์ที่ใช้ร่วมกันพร้อมตัวระบุ group.* หลังจากบันทึกข้อมูลใน App Group ส่วนขยายจะแจ้งให้แอปทราบผ่าน CFNotificationCenter หรือ Darwin Notify
App Groups ถูกเปิดใช้งานในความสามารถของเป้าหมาย: เลือก App Groups และเพิ่มตัวระบุ (เช่น group.com.example.myapp) ทั้งสองเป้าหมาย — แอปหลักและส่วนขยาย — ต้องสามารถเข้าถึงกลุ่มเดียวกันได้ ชุด UserDefaults ช่วยให้อ่านและเขียนข้อมูลในพื้นที่จัดเก็บร่วมกันโดยมีค่าใช้จ่ายเพิ่มเติมน้อยที่สุด
// การบันทึกข้อมูลไปยัง App Group จาก Share Extension
let sharedDefaults = UserDefaults(suiteName: "group.com.example.myapp")
let bookmark: [String: Any] = [
"url": url.absoluteString,
"title": contentText ?? "",
"date": Date().timeIntervalSince1970
]
sharedDefaults?.set(bookmark, forKey: "bookmark_\(Date().timeIntervalSince1970)")
sharedDefaults?.synchronize()
คำถามที่พบบ่อย
Share Extension รับเนื้อหาจากแอปอื่นมายังแอปของคุณ ส่วน Action Extension จะดำเนินการกับเนื้อหาภายในแอปโฮสต์ — แปลข้อความ แก้ไขรูปภาพ Share Extension คือการรับ ส่วน Action Extension คือการแปลง
ขึ้นอยู่กับประเภทเนื้อหาที่แอปของคุณจัดการ สำหรับบุ๊กมาร์ก — public.url สำหรับโปรแกรมแก้ไขรูปภาพ — public.image สำหรับบันทึก — public.plain-text สำหรับหลายประเภท ให้ใช้ NSExtensionActivationRule ร่วมกับเพรดิเคต AND/OR
สาเหตุที่พบบ่อยคือ NSExtensionActivationRule ไม่ถูกต้องหรือ UTI ไม่ตรงกัน ตรวจสอบใน Info.plist: กฎการเปิดใช้งานต้องตรงกับประเภทเนื้อหาที่กำลังทดสอบ นอกจากนี้ ตรวจสอบให้แน่ใจว่าส่วนขยายถูกเปิดใช้งานในการตั้งค่า → แอปของคุณ → Siri และการค้นหา Xcode clean build มักจะแก้ปัญหาได้
ระบบจัดสรรเวลาประมาณ 30 วินาที สำหรับการดำเนินการ หลังจากนั้น iOS จะบังคับยุติกระบวนการของส่วนขยาย สำหรับการดำเนินการที่ยาวนาน ให้ใช้ NSURLSession พื้นหลังและจัดการผลลัพธ์เมื่อเริ่มต้นแอปครั้งถัดไป
ได้ แทนที่จะใช้ SLComposeServiceViewController คุณสามารถใช้ UIViewController ปกติได้ ในกรณีนี้ คุณควบคุมอินเทอร์เฟซได้อย่างสมบูรณ์ อย่างไรก็ตาม คุณต้อง implement ปุ่มส่งและยกเลิกด้วยตนเอง อินเทอร์เฟซแบบกำหนดเอง แนะนำสำหรับสถานการณ์การประมวลผลเนื้อหาที่ไม่ได้มาตรฐาน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ