iOS - 从 Documents 目录中的 bundle 加载 xib

Posted

技术标签:

【中文标题】iOS - 从 Documents 目录中的 bundle 加载 xib【英文标题】:iOS - loading xib from bundle in Documents directory 【发布时间】:2011-06-24 04:44:53 【问题描述】:

我一直致力于通过捆绑 xib 和下载捆绑包并将 xib 加载到这些捆绑包中,让“自定义换肤”界面适用于我的 ios 应用程序。

我已按照此处非常有用的说明进行操作,使其几乎可以正常工作。

loading NSBundle files on iOS

我下载了包,解压后可以看到 xib 文件。我没有在示例中使用任何 TestViewController 代码,而是在使用刚刚下载的 xib 创建视图控制器时这样做:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"gg.bundle"];
    NSBundle *bundle = [NSBundle bundleWithPath:filePath];

    if ( !bundle )
    
        NSLog(@"Error getting bundle");
    

    MyViewController *vc = [MyViewController new];
    [vc initWithNibName:@"CustomDownloadedXib" bundle:bundle];

当我将此视图控制器推送到我的堆栈时,我收到此错误:

*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法在包中加载 NIB:“NSBundle(尚未加载)”,名称为“CustomDownloadedXib””

问题似乎是我的包“尚未加载”。我尝试通过调用来强制加载我的包:

[bundle load]

但这无济于事。

我的方法不正确吗?这似乎是一种直观的方式。

提前致谢!

【问题讨论】:

【参考方案1】:

首先,如果包没有正确创建,它将不会被加载。因此,为了创建正确的包,以下是创建包的步骤:

    通过在 OS X -> Framework & Libraries 下选择名为 bundle 的模板来添加新目标。

    选择新创建的目标并将 BaseSDK 从 OSX 更改为最新的 iOS。

    在 Build Phrases -> Copy Bundle Resources 中添加您想要使用的 .xibs、图像或其他资源。

    在 Build Phrases 中添加 CoreFoundation 框架 -> 将二进制文件与库链接。

    选择iOS设备编译目标。

    将新创建的捆绑包从 Products 目录保存到某个位置。

现在将该包复制到您的主项目中。使用以下代码加载包:

NSString *path = [[NSBundle mainBundle] pathForResource:@"BundleName" ofType:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:path];"

您现在已设置好新捆绑包。

【讨论】:

【参考方案2】:

按照此处的说明进行操作:

loading NSBundle files on iOS

我只是错误地创建了捆绑包!

您需要在 Xcode 中创建包,因为如果您不这样做,它将不会被加载。要创建,请将新目标添加到您的项目,选择 Framework & Library -> Bundle,然后链接到 Core Foundation。然后将要上传到网络的 xib 添加到目标。构建目标,在 Finder 中显示、压缩和上传!

【讨论】:

我明白了:无法加载捆绑包“xyz”,因为无法找到其可执行文件。命令是:NSError *error; BOOL ss = [_bundle preflightAndReturnError:&error];【参考方案3】:

摘自Resource Programming Guide:

在 UIKit 中,应用程序只能从其主包中加载 nib 文件。

听起来你不能做你想做的事。或者至少,Apple 不希望你这样做。当然,您可以始终下载带有图像的.bundle 并将它们加载为UIImage 或类似名称,然后将“活动”皮肤保存到一个已知目录中,该目录是您的应用程序始终查找要使用的图像的目录显示界面。更改皮肤等同于将该路径中的图像资源替换为下载包中的图像资源。

【讨论】:

这是可能的,尽管考虑到我所采取的漏洞可能不是苹果认可的!刚刚解决了我的问题!将发布单独的答案! 确实可以从除主包之外的其他包中加载 nib。在这样的情况下,UIVIewControllers 甚至提供了一个 init 方法来支持这样的——initWithNibName:bundle:【参考方案4】:

经过大量时间后,我发现这是通过库加载资源的常见问题。我错过了添加“CoreFramework”以链接到资源包的步骤,也没有将其复制到客户端应用程序文件夹。这些步骤将有助于正确加载资源包。 #dsiddhapura 的提示帮助我发现了这些问题。

【讨论】:

以上是关于iOS - 从 Documents 目录中的 bundle 加载 xib的主要内容,如果未能解决你的问题,请参考以下文章

从 Documents 目录存储和读取文件 iOS 5

使用 xcode 从 Documents 目录中读取文件

从 Documents 目录在 UIWebview 中打开时,ios-css 和 js 无法在 html 文件中链接

防止篡改 iOS 上 Documents 目录中的文件

iOS 沙盒 - 保护 Documents 目录中的数据

iOS 高效地从 Documents Dir 中解析大型 JSON