Как общаться между приложениями 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).
Он передает полезную нагрузку взад и вперед, используя общий контейнер приложений, и инкапсулирует даже создание самих файлов.
Класс (и пример приложения в репо), похоже, работает хорошо и весьма отзывчив.
Надеюсь, это тоже поможет.
Ответ 3
Apple советует не использовать File Coordination для расширений: https://developer.apple.com/library/ios/technotes/tn2408/_index.html
Ответ 4
Я боролся с той же проблемой и не нашел чистого решения. Еще один хакерский способ решить это - просто запустить таймер в расширении и периодически проверять значения в общих настройках/базе данных контейнера, а затем обновлять, если это необходимо. Не элегантный, но, похоже, он работает.