swift ios8 xcode6 ios-app-extension

swift - Compartir datos entre una extensión de compartir iOS 8 y la aplicación principal



ios8 xcode6 (7)

Recientemente, he estado haciendo una simple extensión de compartir iOS 8 para entender cómo funciona el sistema. Como afirma Apple en su Guía de programación de extensión de la aplicación :

De forma predeterminada, la aplicación que lo contiene y sus extensiones no tienen acceso directo a los contenedores de los demás.

Lo que significa que la extensión y la aplicación que lo contiene no comparten datos. Pero en la misma página, Apple ofrece una solución:

Si desea que su aplicación que contiene y sus extensiones puedan compartir datos, use Xcode o el portal de Desarrolladores para habilitar los grupos de aplicaciones para la aplicación y sus extensiones. Luego, registre el grupo de aplicaciones en el portal y especifique el grupo de aplicaciones para usar en la aplicación que lo contiene.

Entonces es posible usar NSUserDefaults para compartir datos entre la aplicación que contiene y la extensión. Esto es exactamente lo que me gustaría hacer. Pero por alguna razón, no funciona.

En la misma página, Apple sugiere los valores predeterminados estándar:

var defaults = NSUserDefaults.standardUserDefaults()

En una presentación WWDC (217), sugieren un paquete común:

var defaults = NSUserDefaults(suiteName: kDefaultsPackage)

Además, habilité Grupos de aplicaciones para el objetivo de la aplicación que contiene y el objetivo de la extensión, con el mismo nombre de grupo de aplicaciones:

Pero toda esta configuración es para nada. No puedo recuperar los datos que almacené en la aplicación que contiene, de la extensión. Es como si dos objetivos estuvieran utilizando almacenamientos NSUserDefaults completamente diferentes.

Asi que,

  1. ¿Hay una solución para este método?
  2. ¿Cómo puedo compartir datos simples entre la aplicación que contiene y la extensión para compartir? Los datos son solo credenciales de usuario para una API.

Debe usar NSUserDefaults como este y asegúrese de tener habilitado el grupo de aplicaciones en su perfil provisional y el grupo de aplicaciones debe configurarse como un símbolo verde y debe agregarse a su perfil provisional y BundleID.

NSUserDefaults *sharedUserDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"]; [sharedUserDefault setObject:object forKey:@"yourkey"]; [sharedUserDefault synchronize]; NSUserDefaults *sharedUserDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"]; sharedUserDefault value = [sharedUserDefault valueForKey:@"yourkey"];


Así que aparentemente funciona, solo cuando el nombre del grupo se usa como el nombre del conjunto de NSUserDefaults.

La documentación dice que NSUserDefaults.standartUserDefaults () también debería funcionar, pero no es así, y probablemente sea un error.


Deberías usar NSUserDefaults así:

Guardar datos:

NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"]; [shared setObject:object forKey:@"yourkey"]; [shared synchronize];

Leer datos:

NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"]; id value = [shared valueForKey:@"yourkey"]; NSLog(@"%@",value);

¡Eso funcionará bien!


Si usted tiene

group.yourappgroup

utilizar

var defaults = NSUserDefaults(suiteName: "yourappgroup")

Esto funciona para mí


En mi caso, estoy compartiendo datos entre la aplicación principal de iOS y WatchKit. Estoy usando Xcode 6.3.1, iOS Deployment Target 8.3

var defaults = NSUserDefaults(suiteName: "group.yourappgroup.example")

En su viewDidLoad, asegúrese de sincronizar:

override func viewDidLoad() { super.viewDidLoad() defaults?.synchronize() }

Ejemplo de un botón que envía texto pero, por supuesto, puede pasar lo que sea:

@IBAction func btnSend(sender: UIButton) { var aNumber : Int = 0; aNumber = aNumber + 1 //Pass anything with this line defaults?.setObject("/(aNumber)", forKey: "userKey") defaults?.synchronize() }

Luego, por otro lado, asegúrese de que el grupo de aplicaciones coincida:

var defaults = NSUserDefaults(suiteName: "group.yourappgroup.example")

Luego sincronice y cal: (En este caso, "lblNumber" es una etiqueta IBOutlet)

defaults?.synchronize() var tempVar = defaults!.stringForKey("userKey")!; lblNumber.setText(tempVar);

Luego, si desea establecer algo de este lado y sincronizarlo, haga lo mismo y sincronice y asegúrese de que el stringForKey que llama en el otro lado sea el mismo:

defaults?.setObject("sending sample text", forKey: "sampleKey") defaults?.synchronize()

Espero que esto tenga sentido


¡Traduje en la respuesta rápida de Foogry y funciona!

Guardar datos:

let shared = NSUserDefaults(suiteName: "nameOfCreatedGroup") shared("Saved String 1", forKey: "Key1") shared("Saved String 2", forKey: "Key2")

Leer datos:

let shared = NSUserDefaults(suiteName: "nameOfCreatedGroup")! valueToRead1 = shared("Key1") as? String valueToRead2 = shared("Key2") as? String println(valueToRead1) // Saved String 1 println(valueToRead2) // Saved String 2


Así es como lo hice:

  1. Abra su objetivo principal de la aplicación> Capacidades> Grupos de aplicaciones configurados en
  2. Agregue un nuevo grupo de aplicaciones y asegúrese de que esté marcado (por ejemplo, group.com.seligmanventures.LightAlarmFree)
  3. Abre el objetivo de tu reloj (el que tiene la pestaña Capabilities)> Grupos de aplicaciones configurados en
  4. Agregue un nuevo grupo de aplicaciones y asegúrese de que esté marcado (por ejemplo, group.com.seligmanventures.LightAlarmFree, pero debe ser del mismo nombre que el grupo anterior)
  5. Guarde los datos en el grupo de la siguiente manera:

    var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree") defaults?.setObject("It worked!", forKey: "alarmTime") defaults?.synchronize()

  6. Recupere datos del grupo de la siguiente manera:

    var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree") defaults?.synchronize() // Check for null value before setting if let restoredValue = defaults!.stringForKey("alarmTime") { myLabel.setText(restoredValue) } else { myLabel.setText("Cannot find value") }