在iOS 8共享扩展和主应用之间共享数据

最近,我一直在做一个简单的iOS 8共享扩展,以了解系统如何工作。 正如苹果在其应用程序扩展程序指南中所述 :

默认情况下,您的包含应用及其扩展程序无法直接访问彼此的容器。

这意味着扩展和包含应用程序不共享数据。 但苹果在同一页面带来了一个解决scheme:

如果您希望包含应用程序及其扩展程序能够共享数据,请使用Xcode或开发者平台为应用程序及其扩展程序启用应用程序组。 接下来,在门户中注册应用程序组,并指定要在包含应用程序中使用的应用程序组。

然后就可以使用NSUserDefaults来共享包含的应用程序和扩展之间的数据。 这正是我想要做的。 但由于某种原因,这是行不通的。

在同一页面,苹果build议标准的默认值:

var defaults = NSUserDefaults.standardUserDefaults() 

在WWDC的演讲中(217),他们提出了一个共同的scheme:

 var defaults = NSUserDefaults(suiteName: kDefaultsPackage) 

另外,我为包含应用程序目标和扩展目标的应用程序组启用了相同的应用程序组名称: XCode目标功能,应用程序组

但是这一切都是没有用的。 我无法从扩展程序中检索存储在包含应用程序中的数据。 这就像两个目标正在使用完全不同的NSUserDefaults存储。

所以,

  1. 有没有这种方法的解决scheme?
  2. 如何在包含应用程序和共享扩展之间共享简单数据? 数据只是API的用户凭据。

你应该像这样使用NSUserDefaults:

保存数据:

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

读取数据:

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

这将工作正常!

我是这样做的:

  1. 打开您的主要应用程序目标>function>应用程序组设置为打开
  2. 添加一个新的应用程序组,并确保它被勾选(例如group.com.seligmanventures.LightAlarmFree)
  3. 打开您的手表目标(function选项卡)>应用程序组设置为打开
  4. 添加一个新的应用程序组,并确保它被勾选(例如,group.com.seligmanventures.LightAlarmFree – 但必须与上面的组名称相同)
  5. 将数据保存到组中,如下所示:

     var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree") defaults?.setObject("It worked!", forKey: "alarmTime") defaults?.synchronize() 
  6. 从组中检索数据如下:

     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") } 

如果你有

 group.yourappgroup 

使用

 var defaults = NSUserDefaults(suiteName: "yourappgroup") 

这对我有用

所以显然它工作,只有当组名称被用作NSUserDefaults的套件名称

该文档说NSUserDefaults.standartUserDefaults()也应该工作,但它不,这可能是一个错误。

在我的场景中,我将在父iOS应用程序和WatchKit之间共享数据。 我正在使用Xcode 6.3.1,iOS部署目标8.3

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

在你的viewDidLoad确保你同步:

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

button发送文本的例子,但当然你可以通过任何:

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

然后在另一边确保应用程序组匹配:

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

然后同步并cal:(在这种情况下,“lblNumber”是一个IBOutlet标签)

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

然后,如果你想在这一边设置一些东西,然后同步它,那么只需要做同样的事情并进行同步,并确保在另一边调用的stringForKey是相同的:

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

希望这是有道理的

我翻译成迅速foogry的答案,它的作品!

保存数据:

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

读取数据:

 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 

您应该像下面这样使用NSUserDefaults,并确保您必须在您的临时configuration文件中启用了应用程序组,并且应用程序组必须configuration为绿色符号,并且应添加到您的临时configuration文件和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"];