ios - sale - iphone
Cómo comunicarse entre la aplicación iOS que contiene extensión y extensión(no la aplicación host) (5)
Apple desaconseja el uso de la Coordinación de archivos para extensiones: https://developer.apple.com/library/ios/technotes/tn2408/_index.html
TLDR: ¿Es posible enviar mensajes o notificaciones en tiempo real entre la aplicación iOS y su extensión?
Estoy escribiendo una aplicación iOS con una extensión que forma parte del mismo App Group
y comparto los mismos CoreData (base de datos SQLite). Puedo leer y escribir en la base de datos utilizando CoreData desde la aplicación y desde la extensión, ambos comparten el mismo contenido.
Mi pregunta es: ¿Es posible enviar mensajes o notificaciones entre la Aplicación y la extensión para notificar a la otra persona que se actualice si es necesario?
Intenté enviar notificaciones a través de NSNotificationCenter
pero eso no se "sale" de la Aplicación / Extensión, el mismo problema si trato de escribir en el grupo NSUserDefaults
compartido y escucho NSUserDefaultsDidChangeNotification
. Esto funciona dentro de la aplicación pero la extensión no recibe nada (cuando sé que se inició y comparte los mismos NSUserDefaults
). ¿Alguna idea de cómo mantener las cosas sincronizadas?
Hay un truco que puede usar para comunicarse entre dos aplicaciones en iOS o en la aplicación y la extensión. Lo único: no funciona con NetworkExtension ya que Apple está bloqueando cualquier E / S en él.
Puede publicar una notificación en el DarwinNotificationCenter de esta manera:
let notificationName = CFNotificationName("com.notification.name" as CFString)
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
CFNotificationCenterPostNotification(notificationCenter, notificationName, nil, nil, false)
En su aplicación agregue observador:
let notificationName = "com.notification.name" as CFString
let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
CFNotificationCenterAddObserver(notificationCenter,
nil,
{ (
center: CFNotificationCenter?,
observer: UnsafeMutableRawPointer?,
name: CFNotificationName?,
object: UnsafeRawPointer?,
userInfo: CFDictionary?
) in
print("Notification name: /(name)")
},
notificationName,
nil,
CFNotificationSuspensionBehavior.deliverImmediately)
Algunos enlaces: https://github.com/choefele/CCHDarwinNotificationCenter
https://developer.apple.com/documentation/corefoundation/1542572-cfnotificationcentergetdarwinnot
He estado luchando con el mismo problema y tampoco he encontrado una solución limpia. Otra forma pirata de resolver esto es simplemente ejecutar un temporizador en la extensión y verificar los valores en la base de datos / preferencias del contenedor compartido periódicamente y luego actualizarlos si es necesario. No elegante, pero parece funcionar.
Para obtener un medio alternativo para realizar una comunicación bidireccional de propósito general entre la aplicación host y la extensión de la aplicación, intente MMWormhole :
http://www.mutualmobile.com/posts/mmwormhole https://github.com/mutualmobile/MMWormhole
Es una envoltura bastante ligera alrededor de CFNotificationCenter, y utiliza notificaciones de "Darwin" para realizar la comunicación entre procesos ( IPC ).
Pasa las cargas útiles de un lado a otro utilizando el contenedor compartido de las aplicaciones, y encapsula incluso tener que crear los archivos por sí mismos.
La clase (y la aplicación de muestra en el repositorio) parecen funcionar bien y son bastante receptivas.
Espero que esto también ayude.
TLDR: No, pero hay un hack
No existe una verdadera comunicación entre procesos para las aplicaciones de iOS, con o sin extensiones. NSDistributedNotification
aún no ha hecho el viaje de OS X a iOS, y probablemente no lo hará.
Con algunos tipos de extensión, puede abrir URL a través de NSExtensionContext
y usarlas para pasar datos a una aplicación que maneja la URL. Esto trae la aplicación al primer plano, que no suena como lo que quieres.
Sin embargo, hay un truco que podría conseguirte lo que necesitas.
- En lugar de escribir en los valores predeterminados del usuario, escriba en un archivo en el directorio de su grupo de aplicaciones.
- No solo escriba el archivo directamente: use
NSFileCoordinator
para hacer escrituras coordinadas en el archivo. - Implemente
NSFilePresenter
en un objeto que quiera conocer los cambios en el archivo y asegúrese de llamar a[NSFileCoordinator addFilePresenter:someObject]
- Implemente el método
presentedItemDidChange
opcional en su presentador de archivos.
Si hace todo esto correctamente, puede escribir en este archivo desde la aplicación o la extensión, y luego hacer que se le llame automáticamente a PresentItemDidChange en el otro. Como beneficio adicional, por supuesto puede leer el contenido de ese archivo, de modo que puede pasar datos arbitrarios de un lado a otro.