【问题标题】:IOS: calling framework’s View Controller. causes 'Could not load NIB in bundle‘ crashIOS:调用框架的View Controller。导致“无法在包中加载 NIB”崩溃
【发布时间】:2021-10-28 05:26:36
【问题描述】:

我想将单个视图控制器作为框架(称为 LoginFrameWork.framework)分发,可以在任何 App 项目中导入和使用。所以在 XCode 中我创建了一个 iOS Swift 框架项目,在其中我添加了一个视图控制器用 XIB 实例化 来显示登录视图(带有用户名、密码和按钮)。此 LoginViewController 使用公共接口进行编码,因此可以在任何 App 中包含和使用。

框架ViewController如下:

 public class LoginViewController: UIViewController {

    @IBOutlet weak var emailTextField: UITextField!
    
    @IBOutlet weak var passwordTextField: UITextField!
    
    @IBAction func signInButton(_ sender: UIButton) {
        print("username \(emailTextField.text) password \(passwordTextField.text)")
    }
    
    public override func viewDidLoad() {
        super.viewDidLoad()
      
    }

}

接下来,我创建一个带有单个视图控制器 MyAppVC 和一个按钮的 App 项目 MyApp.xcodeproj。单击按钮时,我想从上面创建的框架中推送 LoginViewController。

所以我创建了一个名为 MyApp.xcworkspace 的工作区。在 XCode 中添加上面创建的 LoginFrameWork.framework 和 MyApp.xcodeproj。我连接了 MyAppVC 上的单个按钮以打开 LoginViewController。

import UIKit

import LoginFrameWork

class ViewController: UIViewController {

  
  @IBAction func launchLogin(_ sender: Any) {
    //LoginSDK.start(presentingVC: self)
    var loginVC = LoginViewController(nibName: "LoginViewController", bundle: nil)

     // Present
     self.present(loginVC, animated: true)
    
  }
  override func viewDidLoad() {
        super.viewDidLoad()
    } 

}

但是,这会崩溃并出现以下错误,这表明它找不到 LoginViewController。这可能是因为 (a) 库文件夹中 LoginViewController 的路径错误,或者 (b) 框架没有安装在设备文件夹中 (c) 其他...

(我确实在 MyApp 项目的“常规”选项卡和“嵌入式二进制文件”部分下包含了 LoginFrameWork.framework)

 libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/ramanmtx/Library/Developer/CoreSimulator/Devices/5C88CAFD-85B0-49E2-8641-362D6097DEA6/data/Containers/Bundle/Application/CF14B060-A662-44B7-9CC3-3C7EBD968D21/McApp.app> (loaded)' with name 'LoginViewController''
terminating with uncaught exception of type NSException
CoreSimulator 757.5 - Device: iPhone 12 Pro Max (5C88CAFD-85B0-49E2-8641-362D6097DEA6) - Runtime: iOS 14.5 (18E182) - DeviceType: iPhone 12 Pro Max

【问题讨论】:

    标签: ios swift path frameworks code-reuse


    【解决方案1】:

    将此作为答案发布,如果没有帮助,非常乐意删除。

    我不使用 NIB/XIB 文件,所以我很难复制您正在尝试的内容,但我仍然相信我了解实际问题。这实际上与此无关,而是与捆绑包以及您尝试从中提取内容的位置有关。

    这就是我所做的。例如,假设您拥有三样东西:

    • MyFramework,其中包含
    • MyFile,正在被
    • 使用
    • MyProject

    在我看来这就是你想要的。现在,在 您的 案例中,MyProject 导入包含 MyFileMyFramework。但是...

    MyProject 中,您正在尝试访问MyFramework 捆绑包中的文件:

    var loginVC = LoginViewController(nibName: "LoginViewController", bundle: nil)

    这对我有用。首先,我正在访问一些非常不同的东西——MyFramework 中的 CoreImage 内核文件,将那里的东西实例化为 CIFilters。请记住这一点,但我认为这与您想要的相同。

    MyFramework我打开捆绑文件:

    func openBundleFile(_ named:String) -> String {
        let myBundle = Bundle.init(identifier: "com.MyCompany.MyFramework")
        let kernelPath = (myBundle?.path(forResource: "cikernels", ofType: "bundle"))! + "/" + named + ".cikernel"
        do {
            return try String(contentsOfFile: kernelPath)
        }
        catch let error as NSError {
            return error.description
        }
    }
    

    主要是捆绑标识符。我不认为这对你在 MyProject 中有效,但它可能。

    但我认为最好的路线是:

    • LoginViewController 中创建一个初始化器,它将
    • 使用适当的包名称访问框架内的 NIB/XIB
    • 然后从视图控制器中删除 `init(nibName:bundle:)。

    当然,在您的应用程序中简单地输入捆绑名称可能会起作用。 :-) 但它仍然感觉错了——框架不应该需要这种硬编码!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多