Manos Chorianopoulos

xib bundling issue fix2

1 +# @objc Attributes Fix for SPM Class Resolution
2 +
3 +## Problem
4 +XIB files in SPM couldn't find Swift classes due to name mangling differences between CocoaPods and SPM, causing:
5 +```
6 +Unknown class _TtC41SwiftWarplyFramework_SwiftWarplyFramework40MyRewardsBannerOffersScrollTableViewCell in Interface Builder file.
7 +*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UITableViewCell 0x105f2d060> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key collectionView.'
8 +```
9 +
10 +## Solution
11 +Added explicit `@objc(ClassName)` attributes to all cell classes to provide stable, predictable class names for XIB file instantiation.
12 +
13 +## Classes Updated
14 +
15 +### Table View Cells:
16 +1. **MyRewardsBannerOffersScrollTableViewCell** - `@objc(MyRewardsBannerOffersScrollTableViewCell)`
17 +2. **MyRewardsOffersScrollTableViewCell** - `@objc(MyRewardsOffersScrollTableViewCell)`
18 +3. **ProfileCouponFiltersTableViewCell** - `@objc(ProfileCouponFiltersTableViewCell)`
19 +4. **ProfileHeaderTableViewCell** - `@objc(ProfileHeaderTableViewCell)`
20 +5. **ProfileQuestionnaireTableViewCell** - `@objc(ProfileQuestionnaireTableViewCell)`
21 +6. **ProfileCouponTableViewCell** - `@objc(ProfileCouponTableViewCell)`
22 +
23 +### Collection View Cells:
24 +7. **MyRewardsOfferCollectionViewCell** - `@objc(MyRewardsOfferCollectionViewCell)`
25 +8. **MyRewardsBannerOfferCollectionViewCell** - `@objc(MyRewardsBannerOfferCollectionViewCell)`
26 +9. **ProfileFilterCollectionViewCell** - `@objc(ProfileFilterCollectionViewCell)`
27 +
28 +## What This Fix Does
29 +
30 +### Before:
31 +- Swift name mangling in SPM: `_TtC41SwiftWarplyFramework_SwiftWarplyFramework40MyRewardsBannerOffersScrollTableViewCell`
32 +- XIB files couldn't find the class
33 +- Fell back to generic `UITableViewCell`
34 +- Crashed when trying to connect `collectionView` outlet
35 +
36 +### After:
37 +- Explicit Objective-C name: `MyRewardsBannerOffersScrollTableViewCell`
38 +- XIB files can reliably find the class
39 +- Proper class instantiation
40 +- All outlets connect correctly
41 +
42 +## Benefits
43 +
44 +1. **Stable Class Names** - XIB files always find the correct class regardless of Swift name mangling
45 +2. **SPM Compatibility** - Works consistently in SPM environments
46 +3. **CocoaPods Compatibility** - Maintains backward compatibility
47 +4. **No Swift Regression** - All Swift features and improvements remain intact
48 +5. **Industry Standard** - Common practice for Swift frameworks using XIB files
49 +
50 +## Testing
51 +
52 +After this fix, you should see:
53 +- No more "Unknown class" errors
54 +- Successful XIB instantiation
55 +- Proper outlet connections
56 +- No crashes related to key-value coding compliance
57 +
58 +## Files Modified
59 +
60 +1. `SwiftWarplyFramework/SwiftWarplyFramework/cells/MyRewardsBannerOffersScrollTableViewCell/MyRewardsBannerOffersScrollTableViewCell.swift`
61 +2. `SwiftWarplyFramework/SwiftWarplyFramework/cells/MyRewardsOffersScrollTableViewCell/MyRewardsOffersScrollTableViewCell.swift`
62 +3. `SwiftWarplyFramework/SwiftWarplyFramework/cells/ProfileCouponFiltersTableViewCell/ProfileCouponFiltersTableViewCell.swift`
63 +4. `SwiftWarplyFramework/SwiftWarplyFramework/cells/ProfileHeaderTableViewCell/ProfileHeaderTableViewCell.swift`
64 +5. `SwiftWarplyFramework/SwiftWarplyFramework/cells/ProfileQuestionnaireTableViewCell/ProfileQuestionnaireTableViewCell.swift`
65 +6. `SwiftWarplyFramework/SwiftWarplyFramework/cells/ProfileCouponTableViewCell/ProfileCouponTableViewCell.swift`
66 +7. `SwiftWarplyFramework/SwiftWarplyFramework/cells/MyRewardsOfferCollectionViewCell/MyRewardsOfferCollectionViewCell.swift`
67 +8. `SwiftWarplyFramework/SwiftWarplyFramework/cells/MyRewardsBannerOfferCollectionViewCell/MyRewardsBannerOfferCollectionViewCell.swift`
68 +9. `SwiftWarplyFramework/SwiftWarplyFramework/cells/ProfileFilterCollectionViewCell/ProfileFilterCollectionViewCell.swift`
69 +
70 +This fix should resolve the XIB class resolution issue and eliminate the `NSUnknownKeyException` crashes in SPM environments.
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
7 7
8 import UIKit 8 import UIKit
9 9
10 -@objc public class MyRewardsBannerOfferCollectionViewCell: UICollectionViewCell { 10 +@objc(MyRewardsBannerOfferCollectionViewCell)
11 +public class MyRewardsBannerOfferCollectionViewCell: UICollectionViewCell {
11 @IBOutlet weak var backgroundImage: UIImageView! 12 @IBOutlet weak var backgroundImage: UIImageView!
12 13
13 public override func awakeFromNib() { 14 public override func awakeFromNib() {
......
...@@ -12,7 +12,8 @@ protocol MyRewardsBannerOffersScrollTableViewCellDelegate: AnyObject { ...@@ -12,7 +12,8 @@ protocol MyRewardsBannerOffersScrollTableViewCellDelegate: AnyObject {
12 func didTapProfileButton() 12 func didTapProfileButton()
13 } 13 }
14 14
15 -@objc public class MyRewardsBannerOffersScrollTableViewCell: UITableViewCell { 15 +@objc(MyRewardsBannerOffersScrollTableViewCell)
16 +public class MyRewardsBannerOffersScrollTableViewCell: UITableViewCell {
16 @IBOutlet weak var tagView1: UIView! 17 @IBOutlet weak var tagView1: UIView!
17 @IBOutlet weak var tagLabel1: UILabel! 18 @IBOutlet weak var tagLabel1: UILabel!
18 @IBOutlet weak var tagView2: UIView! 19 @IBOutlet weak var tagView2: UIView!
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
7 7
8 import UIKit 8 import UIKit
9 9
10 -@objc public class MyRewardsOfferCollectionViewCell: UICollectionViewCell { 10 +@objc(MyRewardsOfferCollectionViewCell)
11 +public class MyRewardsOfferCollectionViewCell: UICollectionViewCell {
11 @IBOutlet weak var parentView: UIView! 12 @IBOutlet weak var parentView: UIView!
12 @IBOutlet weak var bannerImage: UIImageView! 13 @IBOutlet weak var bannerImage: UIImageView!
13 @IBOutlet weak var favoriteImage: UIImageView! 14 @IBOutlet weak var favoriteImage: UIImageView!
......
...@@ -11,7 +11,8 @@ protocol MyRewardsOffersScrollTableViewCellDelegate: AnyObject { ...@@ -11,7 +11,8 @@ protocol MyRewardsOffersScrollTableViewCellDelegate: AnyObject {
11 func didSelectOffer(_ offer: OfferModel) 11 func didSelectOffer(_ offer: OfferModel)
12 } 12 }
13 13
14 -@objc public class MyRewardsOffersScrollTableViewCell: UITableViewCell { 14 +@objc(MyRewardsOffersScrollTableViewCell)
15 +public class MyRewardsOffersScrollTableViewCell: UITableViewCell {
15 @IBOutlet weak var categoryLabel: UILabel! 16 @IBOutlet weak var categoryLabel: UILabel!
16 @IBOutlet weak var allButtonView: UIView! 17 @IBOutlet weak var allButtonView: UIView!
17 @IBOutlet weak var allButtonLabel: UILabel! 18 @IBOutlet weak var allButtonLabel: UILabel!
......
...@@ -11,7 +11,8 @@ protocol ProfileCouponFiltersTableViewCellDelegate: AnyObject { ...@@ -11,7 +11,8 @@ protocol ProfileCouponFiltersTableViewCellDelegate: AnyObject {
11 func didSelectFilter(_ filter: CouponFilterModel) 11 func didSelectFilter(_ filter: CouponFilterModel)
12 } 12 }
13 13
14 -@objc public class ProfileCouponFiltersTableViewCell: UITableViewCell { 14 +@objc(ProfileCouponFiltersTableViewCell)
15 +public class ProfileCouponFiltersTableViewCell: UITableViewCell {
15 @IBOutlet weak var titleLabel: UILabel! 16 @IBOutlet weak var titleLabel: UILabel!
16 @IBOutlet weak var collectionView: UICollectionView! 17 @IBOutlet weak var collectionView: UICollectionView!
17 18
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
7 7
8 import UIKit 8 import UIKit
9 9
10 -@objc public class ProfileCouponTableViewCell: UITableViewCell { 10 +@objc(ProfileCouponTableViewCell)
11 +public class ProfileCouponTableViewCell: UITableViewCell {
11 @IBOutlet weak var parentView: UIView! 12 @IBOutlet weak var parentView: UIView!
12 @IBOutlet weak var bannerImage: UIImageView! 13 @IBOutlet weak var bannerImage: UIImageView!
13 @IBOutlet weak var favoriteImage: UIImageView! 14 @IBOutlet weak var favoriteImage: UIImageView!
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
7 7
8 import UIKit 8 import UIKit
9 9
10 -@objc public class ProfileFilterCollectionViewCell: UICollectionViewCell { 10 +@objc(ProfileFilterCollectionViewCell)
11 +public class ProfileFilterCollectionViewCell: UICollectionViewCell {
11 @IBOutlet weak var parentView: UIView! 12 @IBOutlet weak var parentView: UIView!
12 @IBOutlet weak var titleLabel: UILabel! 13 @IBOutlet weak var titleLabel: UILabel!
13 14
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
7 7
8 import UIKit 8 import UIKit
9 9
10 -@objc public class ProfileHeaderTableViewCell: UITableViewCell { 10 +@objc(ProfileHeaderTableViewCell)
11 +public class ProfileHeaderTableViewCell: UITableViewCell {
11 @IBOutlet weak var tagView1: UIView! 12 @IBOutlet weak var tagView1: UIView!
12 @IBOutlet weak var tagLabel1: UILabel! 13 @IBOutlet weak var tagLabel1: UILabel!
13 @IBOutlet weak var tagView2: UIView! 14 @IBOutlet weak var tagView2: UIView!
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
7 7
8 import UIKit 8 import UIKit
9 9
10 -@objc public class ProfileQuestionnaireTableViewCell: UITableViewCell { 10 +@objc(ProfileQuestionnaireTableViewCell)
11 +public class ProfileQuestionnaireTableViewCell: UITableViewCell {
11 @IBOutlet weak var questionnaireBannerImage: UIImageView! 12 @IBOutlet weak var questionnaireBannerImage: UIImageView!
12 13
13 public override func awakeFromNib() { 14 public override func awakeFromNib() {
......