Я разрабатываю приложение для iPhone с расширением Today. Приложение имеет модуль Model, который загружает из/сохраняет в NSUserDefaults. Поскольку я хочу, чтобы эта информация была доступна как для основного приложения, так и для расширения, я использую группу приложений:
let storage = NSUserDefaults(suiteName: "group.etc.etc.etc...")
Как приложение, так и расширение могут получить доступ к информации без каких-либо проблем.
Основное приложение иногда может создавать локальное уведомление для представления пользователю. Это уведомление имеет два действия, связанных с ним (UIUserNotificationAction). Одно из этих действий вызывает запуск некоторого кода на фоне основного приложения. Этот код изменяет информацию NSUserDefaults и запускает синхронизацию. Мой код выглядит примерно так:
func application(application: UIApplication, handleActionWithIdentifier id: String?, forLocalNotification not: UILocalNotification, completionHandler: () -> ()) {
// Interact with model here
// New information gets saved to NSUserDefaults
userDefaultsStorage.synchronize()
completionHandler()
}
Теперь, на Today Ext. Я, естественно, замечаю любые изменения, внесенные в информацию о NSUserDefaults, чтобы я мог перезагрузить интерфейс виджета:
override func viewDidLoad() {
super.viewDidLoad()
// ...
NSNotificationCenter.defaultCenter().addObserverForName(NSUserDefaultsDidChangeNotification, object: nil, queue: NSOperationQueue.mainQueue()) { _ in
self.reload()
}
}
Теперь вот моя проблема:
-
Основное приложение планирует UILocalNotification. Я открываю сегодняшнее представление и смотрю на мой сегодняшний виджет.
-
При срабатывании уведомления в верхней части экрана появляется баннер.
-
Я спускаюсь на этот баннер, чтобы показать два действия, и я выбираю тот, который я упоминал ранее (сегодняшний виджет по-прежнему жив и на экране).
Я знаю, что действие выполняется правильно в фоновом режиме и что изменения вносятся в информацию о NSUserDefaults.
Однако, несмотря на то, что сегодняшний виджет был активным и на экране все это время, действие перезагрузки не запускается. После дальнейшего исследования я могу подтвердить, что NSUserDefaultsDidChangeNotification не работает не (я поставил точку останова, и она не запускалась, а также некоторые другие проверки).
Я знаю, что изменения происходят в результате действия уведомления, потому что если я заставляю перезагрузку виджета (закрывая и открывая представление сегодня), виджет обновляется правильно.
Я видел различные онлайн-учебники, где первое, что они говорят, это прослушивание этого уведомления и обновление виджета, чтобы "виджет синхронизировался с NSUserDefaults". Но дело в том, что AFAICT это уведомление абсолютно бесполезно! Как получилось?
Примечание 1: Когда я изменяю информацию об NSUserDefaults из текущего виджета, уведомление срабатывает правильно.
Примечание 2: Отладка сегодняшнего виджета абсолютно ужасна, кстати. Всегда нужно указывать Xcode "Прикрепить к процессу по имени...", прежде чем он сможет реагировать на точки останова и сбои. И iOS постоянно создает новый процесс для виджета, поэтому мне нужно постоянно указывать Xcode для присоединения снова.