问题描述
我创建了一个 UICollectionView Xib 文件和类文件作为 swift 包。可以访问类文件中的方法,但在我的项目中加载 nib 文件时出现错误。
包链接:https://github.com/PranayChander/package1
项目链接:https://github.com/PranayChander/packman
导入 UIKit 导入包1
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(UINib(nibName: "PackageCollectionViewCell",bundle: nil),forCellWithReuseIdentifier: "cell")
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",for: indexPath) as! PackageCollectionViewCell
cell.configureCell(title: "Pram",subtitle: "dasd")
return cell
}
}
import UIKit
open class PackageCollectionViewCell: UICollectionViewCell {
@IBOutlet open weak var titleLabel: UILabel!
@IBOutlet open weak var subtitleLabel: UILabel!
open override func awakeFromNib() {
super.awakeFromNib()
}
open func configureCell(title: String,subtitle: String) {
self.titleLabel.text = title
self.subtitleLabel.text = subtitle
}
}
Stach 跟踪: 2020-12-21 14:20:37.806065+0530 packman[4341:195092] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法在捆绑包中加载 NIB:”NSBundle /Library /Developer/CoreSimulator/Devices/B98131CA-B121-42B2-A0F5-FC48066C3179/data/Containers/Bundle/Application/95A42061-D137-4F35-94CE-58B8915189C6(name'Collection'Packed'Packed'Packed' *** 首先抛出调用堆栈: ( 0 核心基金会 0x00007fff20420af6 __exceptionPreprocess + 242 1 libobjc.A.dylib 0x00007fff20177e78 objc_exception_throw + 48 2 核心基金会 0x00007fff204209d4 -[NSException initWithCoder:] + 0 3 UIKitCore 0x00007fff24290813 -[UINib instantiateWithOwner:options:] + 495 4 UIKitCore 0x00007fff23d864db -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 907 5 UIKitCore 0x00007fff23d86bdb -[UICollectionView dequeueReusableCellWithReuseIdentifier:forIndexPath:] + 88 6 packman 0x000000010e766d19 $s7packman14ViewControllerC010collectionB0_13cellForItemAtSo012UICollectionB4CellCSo0iB0C_10Foundation9IndexPathVtF + 313 7 packman 0x000000010e766ef5 $s7packman14ViewControllerC010collectionB0_13cellForItemAtSo012UICollectionB4CellCSo0iB0C_10Foundation9IndexPathVtFTo + 165 8 UIKitCore 0x00007fff23d71546 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 410 9 UIKitCore 0x00007fff23d713a6 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 31 10 UIKitCore 0x00007fff23d769cc -[UICollectionView _updateVisibleCellsNow:] + 6148 11 UIKitCore 0x00007fff23d7bc48 -[UICollectionView layoutSubviews] + 351 12 UIKitCore 0x00007fff24bf25b8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2924 13 QuartzCore 0x00007fff27aa2c33 -[CALayer layoutSublayers] + 258 14 QuartzCore 0x00007fff27aa91a5 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 575 15 QuartzCore 0x00007fff27ab4f47 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 65 16 QuartzCore 0x00007fff279f4408 _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 496 17 QuartzCore 0x00007fff27a2b1ef _ZN2CA11Transaction6commitEv + 783 18 UIKitCore 0x00007fff246ae47e __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 81 19 核心基金会 0x00007fff2038f120 CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 12 20 核心基金会 0x00007fff2038e534 __CFRunLoopdoblocks + 434 21 核心基金会 0x00007fff20388f44 __CFRunLoopRun + 899 22 核心基金会 0x00007fff203886d6 CFRunLoopRunSpecific + 567 23 图形服务 0x00007fff2bededb3 GSEventRunModal + 139 24 UIKitCore 0x00007fff24690e0b -[UIApplication _run] + 912 25 UIKitCore 0x00007fff24695cbc UIApplicationMain + 101 26 libswiftUIKit.dylib 0x00007fff54d1e5f2 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGGSgSSSgAJtF + 98 27 包装工 0x000000010e7677da $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 122 28 包装工 0x000000010e76774e $s7packman11AppDelegateC5$mainyyFZ + 46 29 包装工 0x000000010e767829 主 + 41 30 libdyld.dylib 0x00007fff202593e9 开始 + 1 ) libc++abi.dylib:以未捕获的 NSException 类型异常终止 *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法在捆绑包中加载 NIB:”NSBundle /pranaychander/Library/Developer/CoreSimulator/Devices/B98131CA-B121-42B2-A0F5-FC31706 /Containers/Bundle/Application/95A42061-D137-4F35-94CE-58B8915189C6/packman.app>(已加载)',名称为'PackageCollectionViewCell'' 以 NSException 类型的未捕获异常终止 CoreSimulator 732.18.6 - 设备:iPhone 11 Pro (B98131CA-B121-42B2-A0F5-FC48066C3179) - 运行时:iOS 14.3 (18C61) - 设备类型:iPhone 11 Pro
解决方法
您的代码在 NIB 的应用程序包中查找,但找不到(就像在框架包中一样):
无法在捆绑中加载 NIB:'NSBundle /pranaychander/Library/Developer/CoreSimulator/Devices/B98131CA-B121-42B2-A0F5-FC48066C3179/data/Containers/Bundle/Application/914D41376 94CE-58B8915189C6/packman.app>
要么使用框架的标识符来获取正确的包:
let bundle = Bundle(identifier: "com.bundleID.of.the.framework")
collectionView.register(UINib(nibName: "PackageCollectionViewCell",bundle: bundle)....
或者在框架 API 中提供一个工厂函数来获取现成的视图。
,Apple 在文章 Bundling Resources with a Swift Package
中说在访问资源时始终使用 Bundle.module
。包不应假设资源的确切位置。
所以你应该使用这个静态变量作为包参数。
,如果您严格发布 SPM 框架,则可以按照推荐使用上面列出的 Bundle.module
。但是,如果您像我和其他人一样,仍然需要支持 Pod 等。我将 Bundle.module
拉入我的框架并使用 MyFramework.module
作为我的 Bundle。
public class MyFramework: NSObject {
static let bundleName = "MyFramework"
public static let bundle = Bundle(for: Self.self)!
/// Returns the resource bundle associated with the current Swift module. This is required for SPM use
public static var module: Bundle = {
let bundleName = "MyFramework" // May be "MyFramework_MyFramework" for you
let candidates = [
// Bundle should be present here when the package is linked into an App.
Bundle.main.resourceURL,// Bundle should be present here when the package is linked into a framework.
Bundle(for: MyFramework.self).resourceURL,// For command-line tools.
Bundle.main.bundleURL
]
for candidate in candidates {
let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
return bundle
}
}
return MyFramework.bundle
}()
}
一旦你有了它,你就可以使用 MyFramework.module