我的照片分享扩展计划使用相同的设计资产(用于导航以及为照片添加'图章/贴纸)。
如App Sandbox设计指南中所述,沙盒应用程序组 需要共享文件和其他信息可以请求容器 目录作为其权利的一部分。存储这些目录 在〜/ Library / Group Containers /中。 https://developer.apple.com/documentation/foundation/nsfilemanager/1412643-containerurlforsecurityapplicati
目前,资产已捆绑或下载并添加到Documents
文件夹中。如果我想在照片共享扩展程序中使用资产,将所有内容放入~/Library/Group Containers/
并且容器应用程序和扩展程序都从那里获取资产是否有意义?
答案 0 :(得分:35)
关于共享数据:
如果要在iOS8扩展程序和Containing应用程序之间共享文件,则需要将文件写入共享容器或使用共享用户默认值。
来自Apple的iOS8当前文档:
默认情况下,您的应用及其扩展程序没有直接 访问彼此的容器
您想要创建一个应用程序组,并将包含该应用程序及其扩展名添加到该组。使用Xcode 6非常简单,这里是如何在xcode中完成的:
在应用程序组名称中,输入一个常量,如:
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)
此处解决问题的步骤:
转到xcode打开包含应用扩展功能的应用
转到xcode项目中的目标并选择您的应用扩展名
转到构建阶段
展开复制包资源,然后单击“+”按钮并添加 来自finder的图像资源文件夹。
答案 3 :(得分:2)
听起来你想要使用框架。然而,您的框架将主要是资源而不是代码:
OS X广泛使用框架来分发共享代码和资源,例如系统本身的接口。您可以创建自己的框架,为您公司的一个或多个应用程序提供共享代码和资源。您还可以创建包含类库或附加模块的框架,以便将它们分发给其他开发人员。
答案 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...")
}
}
}