无法从动态加载的NSBundle获取CFBundleIdentifier

时间:2013-03-26 15:25:47

标签: ios foundation nsbundle

我正在尝试动态加载一个包,在少数情况下用来代替 mainBundle 。 我设法用一些资源加载bundle,比如Localizable.strings等等。 当我对该bundle使用localizedStringForKey时,会加载正确的本地化字符串。这就是说它的工作原理

尽管如此,我甚至想要一个包标识符。因此,我在包文件夹的根目录中添加了 info.plist 文件,其中包含 CFBundleIdentifier 字符串。 这个,不起作用。当我尝试通过

获取标识符时
[myBundle bundleIdentifier]

我得到一个空值。我试图将文件命名为

Info.plist

MyBundle-Info.plist

其中MyBundle是捆绑包的名称(内容存储在MyBundle.bundle中)。但没有运气。

我真的没有弄到什么问题。我是否必须在信息plist中设置其他键?或者这可能是一个命名问题?任何帮助都将得到更多的赞赏。

1 个答案:

答案 0 :(得分:2)

我最终查看了Core Foundation(毕竟,NSBundle是基于CFBundle的)源代码,并找出了问题所在。所以..

负责收集info.plist内容的函数是CFBundleGetInfoDictionary。只要请求理论上包含在plist中的信息,就会调用此方法。

查看CFBundle.c CFBundleGetInfoDictionary 的实现会检查bundle的_infoDict字段是否已初始化,如果不是,则初始化它:

if (!bundle->_infoDict) bundle->_infoDict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFGetAllocator(bundle), bundle->_url, bundle->_version);

通过在我的 CFBundle 上调用该函数,我没有任何运气,所以我猜测_CFBundleCopyInfoDictionaryInDirectoryWithVersion中一定发生了一些错误。

查看source code,我注意到,根据捆绑包> _version ,会使用不同的路径来搜索信息plist。在这种情况下,版本取决于用于设置捆绑包的目录结构。确切地说,我的版本是 0 ,因为,正如函数_CFBundleURLLooksLikeBundleVersion中指定的(在包初始化期间使用),与 Resources dir的包是这样的:

// check for existence of "Resources" or "Contents" or "Support Files"
    // but check for the most likely one first
    // version 0:  old-style "Resources" bundles
    // version 1:  obsolete "Support Files" bundles
    // version 2:  modern "Contents" bundles
    // version 3:  none of the above (see below)
    // version 4:  not a bundle (for main bundle only)

因此,要完成故事,Info.plist的基本URL将根据版本0在_CFBundleCopyInfoDictionaryInDirectoryWithVersion中初始化

    infoURLFromBase = _CFBundleInfoURLFromBase0;

定义为:

#define _CFBundleInfoURLFromBase0 CFSTR("Resources/Info.plist")

Soooo ...我已将 Info.plist 放在 Resources 目录中,而不是在外面,现在它可以正常工作。

我想我已经完成了所有这次旅行的蠢货,因为这些东西可能写在文档的某处,但我找不到它:(