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

问题描述 投票:0回答:5

我的照片共享扩展计划使用相同的设计资源(用于导航和向照片添加“图章/贴纸”)。

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

目前资源已捆绑或下载并添加到

Documents
文件夹中。如果我想使用照片共享扩展中的资源,将所有内容放入
~/Library/Group Containers/
中并且容器应用程序和扩展都从那里获取资源是否有意义?

ios xcode ios-app-extension ios-app-group asset-catalog
5个回答
40
投票

关于共享数据:

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

来自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"];
    

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

// 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


9
投票

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

正如 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)!
  }
}

请注意,由于上述代码位于框架内部,但将在“应用程序空间”中运行,因此您需要指定捆绑包。 然后,您的应用程序或扩展程序可以在框架中链接,并调用

[AssetService frameworkImageNamed:@"myimage"]

AssetService.frameworkImageNamed("myimage")

警告:尽管返回一个可选的

UIImage?

,如果找不到指定的图像,代码会变得非常生气并且会崩溃。但如果它是你自己的框架,你应该知道里面有什么并捕获这种错误。

    


3
投票

    转到 xcode 打开您的应用程序,其中包含应用程序扩展功能
  1. 转到您的 xcode 项目中的目标并选择您的应用程序扩展名称
  2. 进入构建阶段
  3. 展开复制捆绑资源,然后单击“+”按钮并添加 取景器中的图像资产文件夹。

2
投票

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

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


1
投票
“从框架加载资源”

了解更多详细信息。 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...") } } }

© www.soinside.com 2019 - 2024. All rights reserved.