Обмін та збереження даних між програмами за допомогою груп додатків


85

iOS 8 вчора представив новий API щодо груп додатків. Перш ніж ділитися даними та спілкуватися між програмами було якось брудно, і я вважаю, що саме те, що призначено для виправлення груп додатків.

У своєму додатку я ввімкнув Групи програм і додав нову групу, але я просто не можу знайти жодної документації про те, як нею користуватися. Документація та посилання на API лише вказують, як додати групу.

Отже, що насправді призначено для груп додатків? Чи є десь документація про те, як нею користуватися?

Відповіді:


81

Ще однією перевагою для груп додатків є можливість спільного використання NSUserDefaultsбази даних. Це також працює для розширень додатків (віджети центру повідомлень, власні клавіатури тощо).

Ініціалізуйте свій 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 (наприклад, клавіатурою), вам потрібно переконатися, що ваше розширення має RequestsOpenAccess = YES у своєму файлі Info.plist.
Кіран Панесар

1
Я зробив RequestsOpenAccess = ТАК і дотримуюсь інструкцій, але він все одно не працює для мене на Пристрої, і чудово працює на Емуляторі.
MAC

Та сама проблема зі мною, я інтегрував розширення спільного доступу в своєму додатку, воно працює на симуляторі, але не працює на реальному пристрої ,, я додав RequestOpenAccess = ТАК, але це не працює, моє питання stackoverflow.com/questions/30489894/ ...
Раві Оджха,

3
@MikeRichards не впевнений, але якщо я добре пам’ятаю, до груп додатків додається ідентифікатор команди
Санта Клаус

74

Спільний доступ до даних NSUserDefaults між кількома програмами

Щоб мати спільні стандартні налаштування між програмою та розширенням або між двома програмами, потрібно додати Групу програм у своїх налаштуваннях, виконавши такі дії:

  1. У Навігаторі проектів клацніть на файл * .xcodeproj (повинен бути вгорі).
  2. Праворуч від Навігатора проектів шукайте Проект і Цілі. У розділі "Цілі" натисніть основну ціль (це повинно бути першим пунктом у розділі "Цілі").
  3. Угорі натисніть вкладку Можливості.
  4. У розділі Групи програм натисніть перемикач праворуч, щоб увімкнути Групи програм.
  5. Натисніть кнопку + і додайте групу програм з назвою 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, на якому відображаються всі ваші сертифікати, ідентифікатори, пристрої та профілі забезпечення), щоб увімкнути цю групу? те саме, що push-повідомлення.?
Arbaz Shaikh

Коли ви виконуєте крок 5, він повинен додати групу додатків до порталу розробників Apple, вам не потрібно переходити безпосередньо до порталу розробників, щоб додати його. Після виконання кроку 5 ви можете перейти на портал і побачити, що він повинен був створити його для вас.
TenaciousJay

@TenaciousJay Чудова відповідь. Просто хочу додати Якщо ви хочете запустити програму з додатка func (додаток: UIApplication, URL-адреса openURL: NSURL, параметри: [String: AnyObject]) -> Bool
Taimur Ajmal

чудова відповідь. дякую @TenaciousJay. Я намагаюся отримати змінну та її значення з AppB в AppA, як мені це зробити? Наприклад, якщо "riderCancelledRequest = true" в AppB, як я можу отримати це в AppA?
LizG

37

Групи програм, згідно з моєю інтерпретацією існуючої документації, в основному орієнтовані на розширення, точніше на віджети. Віджети - це їх власний пакет додатків, який співіснує з вашим додатком. Оскільки вони є окремою програмою і, отже, мають власну пісочницю, вам доведеться використовувати групи програм для обміну файлами.

Після деякого grep'e заголовка, я думаю, що я знайшов потрібний API, але насправді був включений як частина iOS 7.

NSFileManagerмає метод, за допомогою containerURLForSecurityApplicationGroupIdentifier:якого ви можете передати ідентифікатор, який ви створили під час увімкнення груп програм для своїх програм:

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

Дякую, я вважаю, ви маєте рацію щодо розширюваності. Я трохи сумнівніший щодо цього методу iOS 7, мені здається досить статичним, iOS 8 представив реальну взаємодію та спілкування між програмами.
streem

@Justafinger Цей метод iOS 7 призначений лише для створення URL-адреси для запису та читання з даних між спільними програмами. Цей конкретний метод є справді корисним (з того, що я бачу на сьогодні) для віджетів, але не для інших розширень.
Wayne Hartman

Ну, я вважаю, що Apple хотіла зробити це простішим в iOS 8, не створюючи програмного контейнера та не надаючи спільний доступ до файлів. Документація стверджує, що ви повинні мати можливість обмінюватися даними за допомогою NSUserDefault. Я думаю, мені чогось не вистачає, бо це для мене не працює.
streem

@Justafinger Я теж не міг приступити NSUserDefaultsдо роботи. Я крейда до бета 1 помилка.
Уейн Хартман,

@WayneHartman Існує обхідне рішення для NSUserDefaultsбази даних. Дивіться мою відповідь.
Санта Клаус

6

Однією з важливих пасток, яку я зачепив сьогодні, є наступне:

У багатьох проектах я бачив єдину ціль програми та з різними ідентифікаторами набору, встановленими для кожної конфігурації цієї цілі. Тут все стає безладним. Розробники планували створити програму налагодження для конфігурації налагодження та робочу програму для цілі випуску.

Якщо ви зробите це, обидва додатки матимуть однакові NSUserDefaults, коли вони будуть налаштовані так

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

Це спричиняє проблеми у багатьох місцях:

  1. Уявіть, що ви встановили ТАК для клавіші, коли користувачеві показаний спеціальний екран-вступ. Інша програма тепер також буде читати ТАК і не відображатиме вступ.
  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()дані, якими не слід ділитися.
Даніель

2

Зберігати

let shared: NSUserDefaults = NSUserDefaults(suiteName: "group.abcapp")!
shared.setObject("abc.png", forKey: "favEmoji")
shared.synchronize()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.