模拟器上的iOS中containerURLForSecurityApplicationGroupIdentifier返回nil

21

背景

iOS8和Extensions中,Apple引入了App组容器(更多信息请参阅此处)。

问题

我们通过NSFileManagercontainerURLForSecurityApplicationGroupIdentifier:方法使用它。在生产环境中,它在AppStore上运行良好(包括iOS8和iOS7)。问题是自从我们团队升级到Xcode 6.1 (6A1052d)以来,在模拟器上该方法返回nil

我们搜寻了很多资料,但没有找到任何线索。即使这个问题或者这个也不适用于这里。

简而言之:问题

NSFileManagercontainerURLForSecurityApplicationGroupIdentifier:方法能在您的模拟器上正常工作吗?有什么办法可以解决这个问题吗?


你找到了任何解决方案吗? - Iqbal Khan
我正在模拟器上使用WatchOS2和iOS9进行开发。这个问题也会偶尔发生在我的开发环境中。我需要每20分钟重置/清除/重新启动才能继续。为什么? - Josh
7个回答

22

containerURLForSecurityApplicationGroupIdentifier: 方法在设备和模拟器中均可使用。

如果您设置了要共享数据以支持组的两个目标(或例如目标和 WatchKit 扩展),但它一直返回 nil,则可能需要检查您的目标设置。

  1. 目标设置 > 通用 > 团队 > 这里应选择您的公司签名团队。如果出现警告和 修复此问题 按钮,请点击该按钮进行修复 :)

  2. 目标设置 > 能力 > 应用组 > 开启 + 显示您的 group.com.yourcompany.yourapp.sharedContainter 组名称("sharedContainer" 是我选择的名称)是否已选中并显示黑色 (不是红色)。如果是红色或有警告和 "修复此问题" 按钮,请重新创建组或创建一个不同的组。

  3. 目标设置 > 构建设置 > 代码签名 > 代码签名 权利:指向您的 Debug 和 Release 的权限文件(类似于 yourApp/yourApp.entitlements)

  4. 目标设置 > 构建设置 > 代码签名 > 代码签名 身份证:确保身份证明是上面选择的团队的一部分。我使用iOS Developer。

  5. 目标设置 > 构建设置 > 代码签名 > 供应 配音:同上,确保您使用的 PP 是所需团队的。我设置为 自动

检查这些设置以实现两个目标之间的数据共享。

希望对您有所帮助。


我的问题在于捆绑标识符,我在应用程序和手表应用程序中使用了相同的捆绑标识符。通常我们需要3个捆绑标识符,即应用程序、手表应用程序和扩展程序。 - user281300
1
就我个人而言,我不得不明确选择正确的“配置文件”(Provisioning Profile),因为使用“自动”选项会导致失败。 - Pascal
“Fix Issue”按钮实际上已经为我解决了这个问题。 - orkoden
太好了!当我修复了第二步时,问题就解决了。 - Josh
有时候问题会再次出现,你会知道这一点是因为在尝试访问容器中的数据时会得到空值。只需重复步骤1、2即可,当能力窗口刷新时,组名会自动从红色变为黑色。XD - Josh

17

我成功解决了这个问题。文档中说:

你的应用必须具有com.apple.security.application-groups授权,以便访问指定的应用程序组。https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/index.html#//apple_ref/occ/instm/NSFileManager/containerURLForSecurityApplicationGroupIdentifier

在我的应用程序中某个地方,我已经从我的应用程序目标/构建设置/代码签名/代码签名授权中删除了授权文件。调试和发布版本都必须包括YOUR_APP.entitlements文件。我的调试版本没有包含它,所以在模拟器上无法工作。


在我的情况下,Xcode 生成了授权文件,但只将其添加到发布配置文件中。非常好的答案,谢谢。 - lewis

5

文档并没有明确指出,但我发现组标识符是大小写敏感的。


1
我发现containerURLForSecurityApplicationGroupIdentifier在xcode 6.2上可以在真机和模拟器上工作。我阅读了这个帖子是因为我也得到了nil,但现在我发现根本原因是我输入的“App Groups”名称有误。
此外,以下是您需要检查的列表:
  1. 确保已经通过xcode或者https://developer.apple.com的web控制台创建了'app groups'
  2. 在'web控制台:Identifiers->App IDs'中,确保在'Development'和'Production'环境下启用了'app groups'
  3. 确保匹配的'Provisioning Profiles'是'active'状态
  4. 包含应用程序和扩展应用程序中的entitlement组名称应与第1步中创建的名称匹配
  5. 确保所有目标的bundle标识符与'web控制台:Identifiers->App IDs'中的标识符相同
  6. 确保所有目标内部的'Team'与web控制台中的一致
  7. 确保在包含应用程序和扩展应用程序目标的'Capabilities'选项卡下选择了正确的组,并且没有红色
  8. 使用cmd+shift+k清除xcode缓存
  9. 重新构建并祈祷

0

我发现在我的情况下,这个错误的原因是一个文件".com.apple.mobile_container_manager.metadata.plist"。当我从这个目录中获取了我的文件后,我删除了其中的所有文件。所以这个文件也被删除了。当你删除这个文件时,应用程序会返回nilcontainerURLForSecurityApplicationGroupIdentifier

所以我把我的代码改成了这样:

    NSURL *groupPath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:YGGroupIdentifier];
    NSArray *fileArray = [fileManager contentsOfDirectoryAtPath:[groupPath path] error:nil];
    for (NSString *filename in fileArray)  {
        if (![filename hasPrefix:@".com"]) {
            [fileManager removeItemAtPath:[[groupPath path] stringByAppendingPathComponent:filename] error:nil];
        }
    }

现在它运行得很好,甚至在模拟器中也是如此。


0

containerURLForSecurityApplicationGroupIdentifier: 方法在我的模拟器上可以工作。但是,如果我删除组文件夹中的所有文件(例如用户在我的应用程序中注销),则该方法在下一次在 Xcode 6.1 中运行时返回 nil。我还使用 Xcode 6.2 和 iOS SDK 8.2 Beta 进行了测试,但它仍然无法正常工作。

代码在真实设备上运行良好。

我也尝试了上述解决方案,但没有成功。


0

对我来说,我的有些混乱(模拟器中不需要运行)。

为了在我的iPhone上运行应用程序,我必须首先重新配置调试环境下的。在设备上调用containerURLForSecurityApplicationGroupIdentifier:非常完美。之后我回到模拟器,然后 - 就可以正常工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接