Как общаться между приложениями iOS, поддерживающими расширение и расширение (не хост-приложение)

TL;DR: Возможно ли отправлять сообщения или уведомления в реальном времени между приложениями iOS и его расширением?

Я пишу приложение iOS с расширением, входящим в один и тот же App Group, и использую одну и ту же базу данных CoreData (база данных SQLite). Я могу читать и писать в базу данных с помощью CoreData из приложения и из расширения, они оба имеют один и тот же контент.

Мой вопрос: возможно ли отправлять сообщения или уведомления между Приложением и добавочным номером, чтобы уведомить другое о необходимости обновления?

Я попытался отправить уведомления через NSNotificationCenter, но это не выходит из приложения/расширения, это же проблема, если я пытаюсь записать в группу shared NSUserDefaults и слушать NSUserDefaultsDidChangeNotification. Это работает внутри приложения, но расширение ничего не получает (когда я знаю, что он запущен, и он имеет один и тот же NSUserDefaults). Любая идея, как синхронизировать вещи?

Ответы

Ответ 1

TL;DR: Нет, но есть хак

Там нет истинной межпроцессной связи для приложений iOS с расширениями или без них. NSDistributedNotification до сих пор не совершил поездку с OS X на iOS и, вероятно, не будет.

С помощью некоторых типов расширений вы можете открывать URL-адреса через NSExtensionContext и использовать их для передачи данных в приложение, которое обрабатывает URL-адрес. Это приносит приложение на передний план, что не похоже на то, что вы хотите.

Существует хак, который может получить вам то, что вам нужно.

  • Вместо того, чтобы писать пользовательские значения по умолчанию, напишите файл в своем каталоге групп приложений.
  • Не просто писать файл напрямую - используйте NSFileCoordinator, чтобы выполнить скоординированное запись в файл.
  • Внесите NSFilePresenter объект, который хочет узнать об изменениях в файле, и обязательно вызовите [NSFileCoordinator addFilePresenter:someObject]
  • Внедрите необязательный метод presentedItemDidChange в презентаторе файла.

Если вы все это сделаете правильно, вы можете записать этот файл из приложения или расширения, а затем presentedItemDidChange будет автоматически вызываться в другом. В качестве бонуса вы можете, конечно, прочитать содержимое этого файла, чтобы вы могли передавать произвольные данные взад и вперед.

Ответ 2

Для альтернативного способа двунаправленной связи общего назначения между хост-приложением и расширением приложения попробуйте MMWormhole:

http://www.mutualmobile.com/posts/mmwormhole https://github.com/mutualmobile/MMWormhole

Своя довольно легкая обертка вокруг CFNotificationCenter и использует уведомления "Darwin" для межпроцессного взаимодействия (IPC).

Он передает полезную нагрузку взад и вперед, используя общий контейнер приложений, и инкапсулирует даже создание самих файлов.

Класс (и пример приложения в репо), похоже, работает хорошо и весьма отзывчив.

Надеюсь, это тоже поможет.

Ответ 4

Я боролся с той же проблемой и не нашел чистого решения. Еще один хакерский способ решить это - просто запустить таймер в расширении и периодически проверять значения в общих настройках/базе данных контейнера, а затем обновлять, если это необходимо. Не элегантный, но, похоже, он работает.