Reputation: 486
I have created an UICollectionView Xib file and class file as a swift package. The methods in class file are accessible but I'm getting an error while loading the nib file in my project.
Link to the package: https://github.com/PranayChander/package1
Link to project: https://github.com/PranayChander/packman
import UIKit import package1
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 Trace: 2020-12-21 14:20:37.806065+0530 packman[4341:195092] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/pranaychander/Library/Developer/CoreSimulator/Devices/B98131CA-B121-42B2-A0F5-FC48066C3179/data/Containers/Bundle/Application/95A42061-D137-4F35-94CE-58B8915189C6/packman.app> (loaded)' with name 'PackageCollectionViewCell'' *** First throw call stack: ( 0 CoreFoundation 0x00007fff20420af6 __exceptionPreprocess + 242 1 libobjc.A.dylib 0x00007fff20177e78 objc_exception_throw + 48 2 CoreFoundation 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 CoreFoundation 0x00007fff2038f120 CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 12 20 CoreFoundation 0x00007fff2038e534 __CFRunLoopDoBlocks + 434 21 CoreFoundation 0x00007fff20388f44 __CFRunLoopRun + 899 22 CoreFoundation 0x00007fff203886d6 CFRunLoopRunSpecific + 567 23 GraphicsServices 0x00007fff2bededb3 GSEventRunModal + 139 24 UIKitCore 0x00007fff24690e0b -[UIApplication _run] + 912 25 UIKitCore 0x00007fff24695cbc UIApplicationMain + 101 26 libswiftUIKit.dylib 0x00007fff54d1e5f2 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 98 27 packman 0x000000010e7677da $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 122 28 packman 0x000000010e76774e $s7packman11AppDelegateC5$mainyyFZ + 46 29 packman 0x000000010e767829 main + 41 30 libdyld.dylib 0x00007fff202593e9 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/pranaychander/Library/Developer/CoreSimulator/Devices/B98131CA-B121-42B2-A0F5-FC48066C3179/data/Containers/Bundle/Application/95A42061-D137-4F35-94CE-58B8915189C6/packman.app> (loaded)' with name 'PackageCollectionViewCell'' terminating with uncaught exception of type NSException CoreSimulator 732.18.6 - Device: iPhone 11 Pro (B98131CA-B121-42B2-A0F5-FC48066C3179) - Runtime: iOS 14.3 (18C61) - DeviceType: iPhone 11 Pro
Upvotes: 5
Views: 4053
Reputation: 1144
.module
. If you are accessing this from outside of the spm library a little extension on Bundle might be helpful.extension Bundle {
public static let blah = Bundle.module
}
Inherits Module From Target
and manually select the module where the view is located.Upvotes: 10
Reputation: 43
If you are strictly releasing your framework for SPM then you can use the Bundle.module
listed above as recommended. But, if you are like me and others and still need to support Pods, etc. I pulled in the Bundle.module
to my framework and used MyFramework.module
as my 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
}()
}
Once you have that you can just use MyFramework.module
Upvotes: 1
Reputation: 5647
Apple says in the article Bundling Resources with a Swift Package
Always use
Bundle.module
when you access resources. A package shouldn’t make assumptions about the exact location of a resource.
So you should use this static variable as bundle parameter.
Upvotes: 7
Reputation: 19602
Your code looks in the apps bundle for the NIB and can not find it (as it is in the frameworks bundle):
Could not load NIB in bundle: 'NSBundle </Users/pranaychander/Library/Developer/CoreSimulator/Devices/B98131CA-B121-42B2-A0F5-FC48066C3179/data/Containers/Bundle/Application/95A42061-D137-4F35-94CE-58B8915189C6/packman.app>
Either use the identifier of the framework to get the correct bundle :
let bundle = Bundle(identifier: "com.bundleID.of.the.framework")
collectionView.register(UINib(nibName: "PackageCollectionViewCell", bundle: bundle)....
Or provide a factory function in the frameworks API to get the ready made view.
Upvotes: 3