在应用和扩展程序之间共享捆绑资产

时间:2014-08-06 00:40:24

标签: objective-c ios8

我的照片分享扩展计划使用相同的设计资产(用于导航以及为照片添加'图章/贴纸)。

  

如App Sandbox设计指南中所述,沙盒应用程序组   需要共享文件和其他信息可以请求容器   目录作为其权利的一部分。存储这些目录   在〜/ Library / Group Containers /中。 https://developer.apple.com/documentation/foundation/nsfilemanager/1412643-containerurlforsecurityapplicati

目前,资产已捆绑或下载并添加到Documents文件夹中。如果我想在照片共享扩展程序中使用资产,将所有内容放入~/Library/Group Containers/并且容器应用程序和扩展程序都从那里获取资产是否有意义?

5 个答案:

答案 0 :(得分:35)

关于共享数据:

如果要在iOS8扩展程序和Containing应用程序之间共享文件,则需要将文件写入共享容器或使用共享用户默认值。

来自Apple的iOS8当前文档:

  

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

您想要创建一个应用程序组,并将包含该应用程序及其扩展名添加到该组。使用Xcode 6非常简单,这里是如何在xcode中完成的:

how to create an app group using xcode 6

在应用程序组名称中,输入一个常量,如:

group.com.bundle.app.soething

这为您的包含应用和扩展程序创建了一个共享容器,允许:

  • 分享NSUserDefaults:

    [[NSUserDefaults alloc] initWithSuiteName:@"group.com.bundle.app.soething"];
    
  • 在文件系统上共享一个目录:

    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.bundle.app.soething"];
    

EDIT 这将打印出我们拥有的所有路径组合:

// App group's path

NSURL  *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.test.app"];

NSLog(@"App group: %@", containerURL.path);



// Bundle path

NSLog (@"Bundle: %@", [[NSBundle mainBundle] bundlePath]);



// Good old Documents path

NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *path = [Paths objectAtIndex:0];

NSLog(@"Documents: %@ ", path);

编辑 - 和Swift:

  • 分享NSUserDefaults:

    var sharedDefaults = NSUserDefaults(suiteName: "group.com.bundle.app.soething")
    
  • 在文件系统上共享一个目录:

    var containerURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.bundle.app.soething")!
    

我希望这可以帮助你:)

资源: Apple的iOS8.0扩展程序开发指南 - https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW1

Apple的iOS8.0 NSFileManager类参考 - https://developer.apple.com/documentation/foundation/nsfilemanager/1412643-containerurlforsecurityapplicati

答案 1 :(得分:8)

我需要在应用和扩展程序之间共享捆绑资源。起初,我想我可以在首次启动时将它们复制到共享组区域,但是如果用户调用扩展并且从不启动应用程序会怎样?

正如mxcl所说,您可以在两个目标中包含资产,但这会扩大最终提交的二进制文件的大小。

我已经确认将资源放在Xcode 6.1中的框架中工作(之前可能有用,但我现在只是尝试了):

您可以在框架或资产目录中拥有独立图像。两者都有效。

在框架中,只需使用可返回UIImage个对象的访问器方法设置一个类。像这样的东西(Objective-C):

@implementation AssetService
+ (UIImage *)frameworkImageNamed:(NSString *)name {
  return [UIImage imageNamed:name
          inBundle:[NSBundle bundleForClass:[self class]]
          compatibleWithTraitCollection:nil];
}
@end

或者在Swift中:

public class AssetService {
  public init() {
  }

  // class method version
  public class func frameworkImageNamed(name: String) -> UIImage? {
    return UIImage(named: name,
                   inBundle: NSBundle(forClass: AssetService.self),
                   compatibleWithTraitCollection: nil)!
  }
}

请注意,由于上面的代码是 in 框架,但是会在" app space"你需要指定包。

然后,您的应用或扩展程序只能链接到框架中,并致电[AssetService frameworkImageNamed:@"myimage"]AssetService.frameworkImageNamed("myimage")

警告:尽管返回了一个可选的UIImage?,如果代码无法找到已命名的图像并且会崩溃,代码会非常生气。但如果它是你自己的框架,你应该知道那里有什么,并抓住这种错误。

答案 2 :(得分:4)

此处解决问题的步骤:

  1. 转到xcode打开包含应用扩展功能的应用

  2. 转到xcode项目中的目标并选择您的应用扩展名

  3. 转到构建阶段

  4. 展开复制包资源,然后单击“+”按钮并添加 来自finder的图像资源文件夹。

答案 3 :(得分:2)

听起来你想要使用框架。然而,您的框架将主要是资源而不是代码:

  

OS X广泛使用框架来分发共享代码和资源,例如系统本身的接口。您可以创建自己的框架,为您公司的一个或多个应用程序提供共享代码和资源。您还可以创建包含类库或附加模块的框架,以便将它们分发给其他开发人员。

https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPFrameworks/Frameworks.html#//apple_ref/doc/uid/10000183i

答案 4 :(得分:0)

资产可以添加到框架中,并可以在应用程序/扩展中重复使用。 有关更多详细信息,请参见"Loading Resources From A Framework"

  public class AmazingView: UIView {
  private func setupView() {
    let bundle = Bundle(for: AmazingView.self)
    guard let image = UIImage(named: "MyImage", in: bundle, compatibileWith: nil) else {
      fatalError("Missing MyImage...")
    }
  }
}