Совместное использование UserDefaults между расширениями

Создание виджета Today, и я использую UserDefaults(suiteName:) для сохранения некоторых данных. В основном приложении я использую UserDefaults.standard(). Это невозможно прочитать (или может быть?) Расширением, поэтому я использую конструктор suiteName:.

Данные, которые пользователь сохраняет в UserDefaults.standard() в главном приложении, должны быть доступны в расширении.

В это время я сохраняю оба значения, чтобы значения могли быть разделены

 UserDefaults.standard().set:...forKey:...
 UserDefaults(suiteName:...)().set:...forKey:...
 ...

Вопрос: должен ли я отбрасывать UserDefaults.standard() все вместе и просто использовать UserDefaults(suiteName:) в своем приложении, или это плохая практика, и если да, то почему?

Изменить: я использую контейнер группы приложений. Для уточнения я спрашиваю, должен ли я просто заменить standard() на имя suite: в течение всего моего проекта?

Ответ 1

Вы не можете использовать общий UserDefaults.standard для обмена данными между хост-приложением и его расширением. Вместо этого вам нужно создать общий контейнер с UserDefaults(suiteName:) для обмена данными.

Несмотря на то, что пакет расширений приложения вложен в свой пакет приложений, работающее расширение приложения и содержащее приложение не имеют прямого доступа к контейнерам друг друга.

Чтобы включить общий доступ к данным, используйте XCode или портал разработчика, чтобы включить группы приложений для содержащего приложения и его расширений. Затем зарегистрируйте группу приложений на портале и укажите группу приложений для использования в содержащем приложении.

После включения групп приложений расширение приложения и содержащее его приложение могут использовать API NSUserDefaults для совместного доступа к пользовательским настройкам. Чтобы включить этот общий доступ, используйте initWithSuiteName: метод для создания нового объекта NSUserDefaults, передавая идентификатор общей группы.

Для получения дополнительной информации обращайтесь по адресу: https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW1

Как использовать группы приложений: https://github.com/pgpt10/Today-Widget

Стандарт или SuiteName?

Используйте стандартный для данных, которые только для хост-приложения. Используйте suiteName для данных, которыми вы хотите поделиться с Extension и Host App. Только не сохраняйте одни и те же данные в обоих. Избегайте избыточности данных. Используйте оба из них в соответствии с контекстом.

Ответ 2

Простой пример:

if let userDefaults = UserDefaults(suiteName: "group.your.bandle.here") {
    userDefaults.set("test 1" as AnyObject, forKey: "key1")
    userDefaults.set("test 2" as AnyObject, forKey: "key2")
    userDefaults.synchronize()
}

и вы можете прочитать это позже:

if let userDefaults = UserDefaults(suiteName: "group.your.bandle.here") {
    let value1 = userDefaults.string(forKey: "key1")
    let value2 = userDefaults.string(forKey: "key2")
    ...
}

Ответ 3

Убедитесь, что App Groups включены для ВСЕХ ваших целей (приложений и целей расширений) на вкладке " Возможности ".

enter image description here

А затем используйте идентификатор группы выше в качестве имени комплекта при создании UserDefaults:

let userDefaults = UserDefaults(suiteName: "group.com.YourCompany.YourApp")