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

时间:2014-06-09 11:02:09

标签: swift ios8 xcode6 ios-app-extension

最近,我一直在制作一个简单的iOS 8共享扩展程序,以了解系统的工作原理。正如Apple在其App Extension Programming Guide中所述:

  

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

这意味着扩展程序和包含应用程序不共享数据。但在同一页面上,Apple提出了一个解决方案:

  

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

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

在同一页面中,Apple建议使用标准默认值:

var defaults = NSUserDefaults.standardUserDefaults()

在WWDC演示文稿(217)中,他们提出了一个共同的方案:

var defaults = NSUserDefaults(suiteName: kDefaultsPackage)

此外,我为包含应用目标和扩展目标的应用组启用了相同的应用组名称: XCode Target capabilities, App Groups

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

所以,

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

8 个答案:

答案 0 :(得分:43)

您应该使用NSUserDefaults:

保存数据:

objc

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

迅速

let defaults = UserDefaults(suiteName: "group.yourgroup")
defaults?.set(5.9, forKey: "yourKey")

读取数据:

objc

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

迅速

let defaults = UserDefaults(suiteName: "group.yourgroup")
let x = defaults?.double(forKey: "yourKey")
print(x)

这样可以正常使用!

答案 1 :(得分:13)

我是这样做的:

  1. 打开您的主应用目标>能力>应用程序组设置为
  2. 添加新的应用程序组并确保已勾选(例如group.com.seligmanventures.LightAlarmFree)
  3. 打开您的观看目标(具有功能标签的目标)>应用程序组设置为
  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")
    }
    

答案 2 :(得分:5)

显然,仅当组名用作NSUserDefaults的套件名称时才有效。

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

答案 3 :(得分:5)

如果你有

group.yourappgroup

使用

var defaults = NSUserDefaults(suiteName: "yourappgroup")

这对我有用

答案 4 :(得分:3)

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

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

在viewDidLoad中确保同步:

    override func viewDidLoad() {
    super.viewDidLoad()

    defaults?.synchronize()

}

按钮发送文本的示例,当然您可以传递任何内容:

 @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()

希望这是有道理的

答案 5 :(得分:2)

我在swift 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

答案 6 :(得分:1)

您可以按照以下步骤共享数据:

  1. 选择您的项目->选择功能选项卡->启用应用程序组->单击'+'->将捆绑包ID粘贴到“组”之后。Enable AppGroups in project capabilities tab
  2. 选择您的扩展程序->选择功能选项卡->启用应用程序组->单击'+'->将捆绑包ID粘贴到“组”之后。Enable AppGroups in Extension capabilities tab

    1. 在要共享其数据的主应用程序中的代码下方放置:

    NSUserDefaults *appGroupData = [[NSUserDefaults alloc]initWithSuiteName:@"group.com.appname"]; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:[self allData]]; // Get my array which I need to share [appGroupData setObject: data forKey:@"Data"]; [appGroupData synchronize];

    1. 您可能会在扩展名中找到对象:

    NSUserDefaults *appGroupData = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.appname"]; NSData *data = [appGroupData dataForKey:@"Data"]; NSArray *arrReceivedData = [NSKeyedUnarchiver unarchiveObjectWithData:data];

答案 7 :(得分:0)

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