从框架加载 nib 文件时出现 NSInternalInconsistencyException

NSInternalInconsistencyException when loading nib file from framework

我在 Xcode 11 上的 swift 中创建了一个名为 TestFramework 的 iOS 框架,并在目标构建设置中将其 Mach-O Type 设置为 static library

我在框架项目中添加了一个名为MyViewController.xibMyViewController.swift的xib文件,并制作了MyViewControllerclasspublic.

然后我创建一个新的 iOS 应用程序项目并将 TestFramework 作为嵌入框架添加到项目中。

我使用下面的代码来测试框架。

let bundle = Bundle(for: MyViewController.self)
print("bundle:", bundle)

let vc = MyViewController(nibName: "MyViewController", bundle: bundle)
print("ViewController:", vc)

我得到结果:

bundle: NSBundle </Users/xxx/TestApp.app> (loaded)
ViewController: <TestFramework.MyViewController: 0x7fce75403c40>

看来一切正常。 但是当我尝试显示 viewcontroller 时,它失败了。我得到了 NSInternalInconsistencyException。

self.present(vc, animated: false, completion: nil)

异常详情:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/xxx/TestApp.app> (loaded)' with name 'MyViewController''

任何想法。谢谢。

静态框架链接会将框架中的代码嵌入到您的应用程序中,与动态库相比,框架中的所有 类 实际上都是主包的一部分。

但是,有一种很好的方法可以使用静态框架中的资源,这可以通过创建一个资源包来实现,该资源包将与静态框架链接,然后通过专门指向该包来加载资源。

  1. 在你的静态框架项目中,创建一个新的 bundle
  2. 将您的捆绑包基础 SDK 更改为 Latest iOS 或您希望从捆绑包的 Build Settings 选项卡支持的任何平台
  3. 在项目检查器中,将包作为目标依赖项添加到 Build Phases 选项卡下的静态库
  4. 在您的测试应用程序中,链接静态框架后,将您的资源包添加到 Build Phases 选项卡中的 Copy Bundle Resources 列表。

这是用于设置的,现在您可以在代码中使用它了:

    guard let bundlePath = Bundle.main.path(forResource: "<your bundle name>" ofType: "bundle"),
          let bundle = Bundle(path: bundlePath) else { return }
    let viewController = MyViewController(nibName: "<your nib name>" bundle: bundle)

您也可以在静态框架内使用此代码,但您应始终注意资源包应始终添加到使用该框架的每个应用程序的 Copy Bundle Resources 中。

在动态 libraries/frameworks 的情况下,类 将从它们的包中动态加载,因此访问资源更加直接。