การสื่อสารและการเก็บรักษาข้อมูลระหว่างแอพด้วย App Groups


87

iOS 8 เปิดเผย API ใหม่เมื่อวานนี้เกี่ยวกับ App Groups มันเป็นเรื่องยุ่งมากก่อนที่จะแชร์ข้อมูลและสื่อสารระหว่างแอพและฉันเชื่อว่านั่นคือสิ่งที่ App Groups ตั้งใจจะแก้ไข

ในแอปของฉันฉันได้เปิดใช้งานกลุ่มแอปและเพิ่มกลุ่มใหม่ แต่ไม่พบเอกสารเกี่ยวกับวิธีการใช้งาน การอ้างอิงเอกสารและ API ระบุวิธีการเพิ่มกลุ่มเท่านั้น

App Groups มีไว้เพื่อทำอะไร? มีเอกสารเกี่ยวกับวิธีการใช้งานหรือไม่?

คำตอบ:


83

ประโยชน์อีกอย่างของ App Groups คือความสามารถในการแชร์NSUserDefaultsฐานข้อมูล นอกจากนี้ยังใช้ได้กับ App Extensions (วิดเจ็ตศูนย์การแจ้งเตือนคีย์บอร์ดแบบกำหนดเอง ฯลฯ )

เริ่มต้นNSUserDefaultsวัตถุของคุณเช่นนี้ในทุกแอปพลิเคชันในกลุ่มแอปและจะแชร์ฐานข้อมูล:

วัตถุประสงค์ -C:

[[NSUserDefaults alloc] initWithSuiteName:@"<group identifier>"];

รวดเร็ว:

NSUserDefaults(suiteName: "<group identifier>")

โปรดทราบว่าทุกอย่างจาก[NSUserDefaults standardUserDefaults]ฐานข้อมูลสำหรับแต่ละแอปพลิเคชันจะไม่ถูกส่งต่อไปยังฐานข้อมูลนี้

เอกสารให้เป็นตัวอย่างที่ถูกต้องเช่นกัน (ในฐานะของ Beta 3)

และอย่าลืมซิงโครไนซ์ฐานข้อมูล:

[yourDefaults synchronize];

2
ใช้งานได้กับโปรแกรมจำลองเท่านั้น (XCode 6 beta 5, iOS 8 beta 5)
iOS Dev

8
หมายเหตุ: หากคุณใช้สิ่งนี้กับส่วนขยาย iOS 8 (เช่นแป้นพิมพ์) คุณจะต้องตรวจสอบให้แน่ใจว่าส่วนขยายของคุณมี RequestOpenAccess = YES ในไฟล์ Info.plist
Kiran Panesar

1
ฉันใช้ RequestOpenAccess = ใช่แล้วและทำตามคำแนะนำ แต่มันยังไม่ได้ผลสำหรับฉันบนอุปกรณ์และทำงานได้ดีบน Emulator มีอะไรเฉพาะสำหรับอุปกรณ์หรือไม่
MAC

ปัญหาเดียวกันกับฉันฉันได้รวมส่วนขยายการแชร์ในแอปของฉันมันทำงานบนโปรแกรมจำลอง แต่ไม่ทำงานบนอุปกรณ์จริงฉันได้เพิ่ม RequestOpenAccess = ใช่แล้ว แต่มันไม่ได้ผลคำถามของฉันคือstackoverflow.com/questions/30489894/ …
Ravi Ojha

3
@MikeRichards ไม่แน่ใจ แต่ถ้าจำไม่ผิดกลุ่มแอปจะขึ้นต้นด้วยรหัสทีม
ซานตาคลอส

74

การแบ่งปันข้อมูล NSUserDefaults ระหว่างหลายแอพ

หากต้องการใช้ค่าเริ่มต้นร่วมกันระหว่างแอปและส่วนขยายหรือระหว่าง 2 แอปคุณต้องเพิ่มกลุ่มแอปในการตั้งค่าโดยใช้ขั้นตอนต่อไปนี้:

  1. ใน Project Navigator ให้คลิกที่ไฟล์ * .xcodeproj (ควรอยู่ด้านบนสุด)
  2. ทางด้านขวาของ Project Navigator ให้มองหา Project และ Targets ภายใต้เป้าหมายให้คลิกที่เป้าหมายหลักของคุณ (ควรเป็นสิ่งแรกภายใต้เป้าหมาย)
  3. คลิกที่แท็บความสามารถทางด้านบน
  4. ในส่วนกลุ่มแอปให้คลิกสวิตช์ทางด้านขวาเพื่อเปิดกลุ่มแอป
  5. คลิกที่ปุ่ม + และเพิ่ม App Group ชื่อgroup.com.company.myApp group.com.company.myApp
  6. ไปที่สถานที่เดียวกันในแอปอื่น ๆ ของคุณและตอนนี้กลุ่มนี้จะพร้อมให้เลือก เปิดกลุ่มนี้สำหรับแต่ละแอปที่จะใช้ข้อมูลที่แชร์นี้

หมายเหตุ: หากคุณไปที่พอร์ทัลนักพัฒนาของ Apple (เว็บไซต์ Apple ที่แสดงใบรับรองตัวระบุอุปกรณ์และโปรไฟล์การจัดเตรียมทั้งหมดของคุณ) และไปที่ตัวระบุ> กลุ่มแอปคุณจะเห็นกลุ่มแอปใหม่นี้

ในการจัดเก็บข้อมูล:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")!
userDefaults.setObject("user12345", forKey: "userId")
userDefaults.synchronize()

ในการดึงข้อมูล:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
if let testUserId = userDefaults?.objectForKey("userId") as? String {
  print("User Id: \(testUserId)")
}

2
ขอบคุณ! ต้องใช้เวลาในการค้นหาในเอกสารเพื่อหาวิธีทำและฉันคิดว่าคนอื่น ๆ อาจชอบขั้นตอนที่ฉันทำ
TenaciousJay

ขอบคุณสำหรับคำอธิบายโดยละเอียด ... ! เราจำเป็นต้องสร้างใบรับรองจากพอร์ทัลนักพัฒนาของ Apple (เว็บไซต์ Apple ที่แสดงใบรับรองตัวระบุอุปกรณ์และโปรไฟล์การจัดเตรียมทั้งหมดของคุณ) เพื่อเปิดใช้งานกลุ่มนี้หรือไม่ เหมือนกับการแจ้งเตือนแบบพุช
Arbaz Shaikh

เมื่อคุณทำขั้นตอนที่ 5 ควรเพิ่ม App Group ในพอร์ทัลนักพัฒนาของ Apple คุณไม่ควรไปที่พอร์ทัลนักพัฒนาโดยตรงเพื่อเพิ่ม หลังจากทำขั้นตอนที่ 5 แล้วคุณสามารถไปที่พอร์ทัลและดูว่าควรสร้างให้คุณแล้ว
TenaciousJay

@TenaciousJay คำตอบที่ยอดเยี่ยม แค่ต้องการเพิ่มหากคุณต้องการเปิดแอปจากแอปพลิเคชัน func (แอป: UIApplication, openURL url: NSURL, ตัวเลือก: [String: AnyObject]) -> Bool
Taimur Ajmal

คำตอบที่ดี ขอบคุณ @TenaciousJay ฉันกำลังพยายามดึงตัวแปรและค่าจาก AppB ไปยัง AppA ฉันจะทำอย่างไร ตัวอย่างเช่นถ้า "riderCancelledRequest = true" ใน AppB ฉันจะดึงข้อมูลนี้ใน AppA ได้อย่างไร
LizG

37

กลุ่มแอปพลิเคชันตามการตีความเอกสารที่มีอยู่ของฉันมีเป้าหมายหลักสำหรับส่วนขยายโดยเฉพาะอย่างยิ่งสำหรับวิดเจ็ต วิดเจ็ตคือชุดแอปพลิเคชันของตนเองที่อยู่ร่วมกับแอปของคุณ เนื่องจากเป็นแอปพลิเคชันแยกต่างหากดังนั้นจึงมีแซนด์บ็อกซ์ของตัวเองคุณจึงต้องใช้ App Groups เพื่อแชร์ไฟล์

หลังจาก grep'ing ส่วนหัวบางส่วนฉันคิดว่าฉันพบว่าจำเป็นต้องใช้ API แต่จริงๆแล้วถูกใส่ไว้ในส่วนหนึ่งของ iOS 7

NSFileManagerมีวิธีการcontainerURLForSecurityApplicationGroupIdentifier:ที่คุณสามารถส่งผ่านตัวระบุที่คุณสร้างขึ้นเมื่อเปิดกลุ่มแอปสำหรับแอปของคุณ:

NSURL *containerURL = [[NSFileManager defaultManager] 
           containerURLForSecurityApplicationGroupIdentifier:@"group.com.company.app"];

ขอบคุณฉันเชื่อว่าคุณพูดถูกเกี่ยวกับการขยายขอบเขต ฉันสงสัยเล็กน้อยเกี่ยวกับวิธีการ iOS 7 นี้ดูเหมือนจะค่อนข้างคงที่สำหรับฉัน iOS 8 ได้แนะนำการโต้ตอบและการสื่อสารระหว่างแอปอย่างแท้จริง
สตรีม

@Justafinger วิธีการ iOS 7 นี้ใช้สำหรับการสร้าง URL เพื่อเขียนและอ่านจากข้อมูลระหว่างแอปพลิเคชันที่แชร์เท่านั้น วิธีเฉพาะนี้มีประโยชน์มากเท่านั้น (จากที่ฉันเห็นจนถึงตอนนี้) สำหรับวิดเจ็ต แต่ไม่ใช่ส่วนขยายอื่น ๆ
Wayne Hartman

ฉันเชื่อว่า Apple ต้องการทำให้สิ่งนี้ง่ายขึ้นใน iOS 8 โดยไม่ต้องสร้างคอนเทนเนอร์โดยใช้โปรแกรมและแชร์ไฟล์ที่กำหนดเอง เอกสารระบุว่าคุณควรจะแชร์ข้อมูลได้โดยใช้ NSUserDefault ฉันเดาว่าฉันพลาดอะไรบางอย่างไปเพราะนั่นไม่เหมาะกับฉัน
สตรีม

@ จัสตาฟิงเกอร์ฉันไม่สามารถNSUserDefaultsไปทำงานได้เช่นกัน ฉันชอล์กเพื่ออัพข้อบกพร่องเบต้า 1
Wayne Hartman

@WayneHartman มีวิธีแก้ปัญหาสำหรับNSUserDefaultsฐานข้อมูล ดูคำตอบของฉัน
ซานตาคลอส

6

กับดักที่สำคัญอย่างหนึ่งที่ฉันใช้ในวันนี้มีดังต่อไปนี้:

ในหลายโครงการฉันเห็นเป้าหมายแอปเดียวและมีการตั้งค่าตัวระบุกลุ่มที่แตกต่างกันสำหรับแต่ละการกำหนดค่าของเป้าหมายนั้น ที่นี่สิ่งต่างๆยุ่งเหยิง สิ่งที่นักพัฒนาตั้งใจไว้คือสร้างแอปดีบักสำหรับการกำหนดค่าการดีบักและแอปที่ใช้งานจริงสำหรับเป้าหมายรุ่น

หากคุณทำเช่นนั้นทั้งสองแอปจะแชร์ NSUserDefaults เดียวกันเมื่อมีการตั้งค่าเช่นนั้น

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
userDefaults!.setObject("user12345", forKey: "userId")
userDefaults!.synchronize()

สิ่งนี้ทำให้เกิดปัญหาในหลาย ๆ ที่:

  1. สมมติว่าคุณตั้งค่า YES สำหรับคีย์เมื่อมีการแสดงหน้าจอแนะนำแอปพิเศษให้ผู้ใช้เห็น ขณะนี้แอปอื่นจะอ่าน YES และไม่แสดงบทนำ
  2. ใช่บางแอปยังจัดเก็บโทเค็น oAuth ไว้ในค่าเริ่มต้นของผู้ใช้ อย่างไรก็ตาม ... ขึ้นอยู่กับการใช้งานแอปจะรับรู้ว่ามีโทเค็นและเริ่มดึงข้อมูลโดยใช้โทเค็นที่ไม่ถูกต้อง มีโอกาสสูงที่จะล้มเหลวด้วยข้อผิดพลาดแปลก ๆ

วิธีแก้ปัญหานี้โดยทั่วไปคือนำหน้าคีย์เริ่มต้นด้วยการกำหนดค่าปัจจุบันที่สร้างขึ้น คุณสามารถตรวจจับการกำหนดค่าได้อย่างง่ายดายที่รันไทม์โดยการตั้งค่าตัวระบุบันเดิลที่แตกต่างกันสำหรับการกำหนดค่าของคุณ NSBundle.mainBundle()แล้วก็อ่านบ่งชี้กลุ่มจาก หากคุณมีตัวระบุบันเดิลเดียวกันคุณต้องตั้งค่ามาโครตัวประมวลผลล่วงหน้าที่แตกต่างกันเช่น

#ifdef DEBUG
  NSString* configuration = @"debug";
#elif RELEASE
  NSString* configuration = @"release";
#endif

ใน Swift จะมีลักษณะเกือบเหมือนกัน:

#if DEBUG
  let configuration = "debug"
#elseif RELEASE
  let configuration = "release"
#endif

8
ปัญหาของคุณเกิดขึ้นเนื่องจากคุณผสมข้อมูลทั้งหมดของคุณใน UserDefaults ที่ใช้ร่วมกัน คุณควรใช้NSUserDefaults.standardUserDefaults()สำหรับข้อมูลที่ไม่ควรแชร์
Daniel

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.