【发布时间】:2014-11-29 02:36:54
【问题描述】:
是否可以从应用扩展中获取包含应用的NSBundle?我想获取主应用程序的显示名称,而不是扩展程序的显示名称。
【问题讨论】:
标签: ios swift nsbundle ios-app-extension
是否可以从应用扩展中获取包含应用的NSBundle?我想获取主应用程序的显示名称,而不是扩展程序的显示名称。
【问题讨论】:
标签: ios swift nsbundle ios-app-extension
根据@phatblat 的回答,这是一个不太可能因文件结构更改而中断的解决方案。
extension Bundle {
/// Return the main bundle when in the app or an app extension.
static var app: Bundle {
var components = main.bundleURL.path.split(separator: "/")
var bundle: Bundle?
if let index = components.lastIndex(where: { $0.hasSuffix(".app") }) {
components.removeLast((components.count - 1) - index)
bundle = Bundle(path: components.joined(separator: "/"))
}
return bundle ?? main
}
}
【讨论】:
+mainBundle 方法返回包含“当前应用程序可执行文件”的包,当从扩展程序中调用时,它是应用程序的子文件夹。
此解决方案涉及从包的 URL 中剥离两个目录级别,当它以“appex”结尾时。
Objective-C
NSBundle *bundle = [NSBundle mainBundle];
if ([[bundle.bundleURL pathExtension] isEqualToString:@"appex"]) {
// Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex
bundle = [NSBundle bundleWithURL:[[bundle.bundleURL URLByDeletingLastPathComponent] URLByDeletingLastPathComponent]];
}
NSString *appDisplayName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
斯威夫特 2.2
var bundle = NSBundle.mainBundle()
if bundle.bundleURL.pathExtension == "appex" {
// Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex
bundle = NSBundle(URL: bundle.bundleURL.URLByDeletingLastPathComponent!.URLByDeletingLastPathComponent!)!
}
let appDisplayName = bundle.objectForInfoDictionaryKey("CFBundleDisplayName")
斯威夫特 3
var bundle = Bundle.main
if bundle.bundleURL.pathExtension == "appex" {
// Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex
let url = bundle.bundleURL.deletingLastPathComponent().deletingLastPathComponent()
if let otherBundle = Bundle(url: url) {
bundle = otherBundle
}
}
let appDisplayName = bundle.object(forInfoDictionaryKey: "CFBundleDisplayName")
如果 iOS 扩展的 pathExtension 或目录结构发生变化,这将中断。
【讨论】:
UIManagedDocument 的托管对象模型。
try? 来减少对 do/catch 语句的需求。