89

iOS 8 昨天发布了一个关于 App Groups 的新 API。以前在应用程序之间共享数据和通信有点混乱,我相信这正是应用程序组想要纠正的。

在我的应用程序中,我启用了应用程序组并添加了一个新组,但我找不到任何有关如何使用它的文档。文档和 API 参考仅说明如何添加组。

那么 App Groups 的真正意图是什么?是否有任何关于如何使用它的文档?

4

6 回答 6

84

App Groups 的另一个好处是能够共享NSUserDefaults数据库。这也适用于应用扩展(通知中心小部件、自定义键盘等)。

NSUserDefaults在应用组中的所有应用程序中像这样初始化您的对象,它们将共享数据库:

目标-C:

[[NSUserDefaults alloc] initWithSuiteName:@"<group identifier>"];

迅速:

NSUserDefaults(suiteName: "<group identifier>")

请记住[NSUserDefaults standardUserDefaults],每个应用程序的数据库中的所有内容都不会转移到该数据库中。

文档也提供了一个正确的示例(从 Beta 3 开始)。

并且不要忘记同步数据库:

[yourDefaults synchronize];
于 2014-06-05T14:39:50.673 回答
76

在多个应用程序之间共享 NSUserDefaults 数据

为了在应用程序和扩展程序之间或两个应用程序之间共享默认值,您必须使用以下步骤在设置中添加应用程序组:

  1. 在 Project Navigator 中单击 *.xcodeproj 文件(应该在顶部)。
  2. 在 Project Navigator 的右侧,查找 Project and Targets。在目标下单击您的主要目标(应该是目标下的第一件事)。
  3. 在顶部,单击功能选项卡。
  4. 在 App Groups 部分中,单击右侧的开关以打开 App Groups。
  5. 单击 + 按钮并添加一个名为group.com.company.myApp的应用程序组。
  6. 转到其他应用程序中的相同位置,现在应该可以选择该组。为将使用此共享数据的每个应用打开此组。

注意:如果您访问 Apple Developer Portal(显示所有证书、标识符、设备和配置文件的 Apple 网站)并转到 Identifiers > App Groups,您应该会看到这个新的 App Group。

存储数据:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")!
userDefaults.setObject("user12345", forKey: "userId")
userDefaults.synchronize()

要检索数据:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
if let testUserId = userDefaults?.objectForKey("userId") as? String {
  print("User Id: \(testUserId)")
}
于 2015-10-27T17:59:23.113 回答
37

根据我对现有文档的解释,应用程序组主要针对扩展,更具体地说,针对小部件。小部件是它们自己的应用程序包,与您的应用程序共存。由于它们是一个单独的应用程序,因此有自己的沙箱,因此您需要使用应用程序组来共享文件。

经过一些标头grep'ing,我想我找到了所需的API,但实际上是作为iOS 7的一部分放入的。

NSFileManager上面有一个方法containerURLForSecurityApplicationGroupIdentifier:,您可以在其中传递您在为您的应用打开应用组时创建的标识符:

NSURL *containerURL = [[NSFileManager defaultManager] 
           containerURLForSecurityApplicationGroupIdentifier:@"group.com.company.app"];
于 2014-06-04T02:58:38.737 回答
6

我今天发现的一个重要陷阱如下:

在许多项目中,我看到了一个应用程序目标,并为该目标的每个配置设置了不同的包标识符。这里事情变得一团糟。开发人员的意图是为调试配置创建一个调试应用程序,为发布目标创建一个生产应用程序。

如果您这样做,两个应用程序将在设置时共享相同的 NSUserDefaults

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
userDefaults!.setObject("user12345", forKey: "userId")
userDefaults!.synchronize()

这会导致很多地方出现问题:

  1. 想象一下,当一个特殊的 app-intro-screen 显示给用户时,您将一个键设置为 YES。另一个应用程序现在也将显示“是”并且不显示介绍。
  2. 是的,一些应用程序还将 oAuth 令牌存储在其用户默认值中。无论如何...根据实现,应用程序将识别出有一个令牌并开始使用错误的令牌检索数据。这很可能会因奇怪的错误而失败。

通常,此问题的解决方案是使用当前构建的配置为默认键添加前缀。通过为配置设置不同的包标识符,您可以在运行时轻松检测配置。然后只需从NSBundle.mainBundle(). 如果您有相同的包标识符,则需要设置不同的预处理器宏,例如

#ifdef DEBUG
  NSString* configuration = @"debug";
#elif RELEASE
  NSString* configuration = @"release";
#endif

在 Swift 中,它看起来几乎是一样的:

#if DEBUG
  let configuration = "debug"
#elseif RELEASE
  let configuration = "release"
#endif
于 2015-12-10T23:31:13.023 回答
2

储藏

let shared: NSUserDefaults = NSUserDefaults(suiteName: "group.abcapp")!
shared.setObject("abc.png", forKey: "favEmoji")
shared.synchronize()
于 2016-09-06T10:01:21.607 回答
2

App Group允许您在来自同一开发团队(帐户)的不同进程(应用程序、扩展...)之间共享数据(用户默认值、文件、CoreData(管理模型图)、POSIX 锁)。它创建了一个shared containerwhitid应该从group.保存/缓存数据开始,您可以访问思想 url 和 IPC

App Group与 UserDefaults 一起使用

  1. 为您将获得访问权限的所有目标(应用程序、扩展程序...)添加App Group具有相同 ID 的功能 在此处输入图像描述

创建后,您可以在Apple Developer上进行检查。证书、ID 和配置文件 -> 标识符 -> 所有组

在此处输入图像描述

  1. 从 Application1 写入
let defaults = UserDefaults(suiteName: "group.goforit")
defaults?.setValue("Hello World!", forKey: "key1")
  1. 从 Application2 读取
let defaults = UserDefaults(suiteName: "group.goforit")
let result = defaults?.value(forKey: "key1") //Hello World!

shared container根位置单个 URL。

let rootURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.goforit")

//file:///Users/alex/Library/Developer/CoreSimulator/Devices/1AF41817-FE2E-485A-A592-12C39C0B0141/data/Containers/Shared/AppGroup/DC14D43F-2C2C-4771-83BE-64A9F54BD2E1/
于 2021-03-03T12:45:50.457 回答