Error -> init(coder:) has not been implemented

I'm trying to access another class in my CollectionView Controller but when I try and initialise the class I get the error

Here is the class

@MainActor
class AlbumsViewModel {

    private let albumService: AlbumService
    private let favouritesService: FavouritesService
    private let recommendationService: RecommendationService

    @Published var favourites = [Bool]()
    @Published var recommendedAlbums = [Album]()
    @Published var allAlbums = [Album]() {

        didSet {
            updateFavourites()
        }

    }

    init(albumService: AlbumService, favouritesService: FavouritesService, recommendationService: RecommendationService) {

        self.albumService = albumService
        self.favouritesService = favouritesService
        self.recommendationService = recommendationService

    }
...(functions here)

Collectionview Controller Class

class CVC: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    var viewModel: AlbumsViewModel

    init?(viewModel: AlbumsViewModel, coder: NSCoder) {
        self.viewModel = viewModel

        super.init(coder: coder)
    }

    required init?(coder: NSCoder) {

        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.delaysContentTouches = false

        Task {
            print(viewModel.allAlbums)
        }


    } // End viewDidLoad
...

Trying to recreate this https://martinmitrevski.com/2021/07/11/ml-recommendation-app-with-create-ml-on-ios-15/

Answered by robnotyou in 701475022

You are instantiating the CVC directly from your Storyboard.
So you can't pass in the viewModel property.

You will have to think of another way to use viewModel in CVC. For example, as a global singleton, like this...

In AlbumsViewModel:

static let shared = AlbumsViewModel(albumService:favouritesService:recommendationService:) // however you initialise it

...then in CVC, refer to

AlbumsViewModel.shared

...or create a shortcut property

let viewModel = AlbumsViewModel.shared

Where is the error... which class, which line?

The error is in the the collection view class at required init?(coder: NSCoder) {         fatalError("init(coder:) has not been implemented")     }

How are you initializing the CVC?

The init method above that

You have defined CVC init(coder:) to throw a fatal error.

You don't show where you are initializing the CVC... ...but it seems that init(coder:) is being called, since you are seeing the error.

You need to implement a proper init(coder:)...

required init?(coder: NSCoder) {
    super.init(coder: coder)
    /// any other setup action here... what about viewModel?
}

... or use your custom initializer instead.

You should add at least super.init and remove fatal error.

What I often do is define a sharedInit() func that I call in all init, including coder.

        self.sharedInit()  
Accepted Answer

You are instantiating the CVC directly from your Storyboard.
So you can't pass in the viewModel property.

You will have to think of another way to use viewModel in CVC. For example, as a global singleton, like this...

In AlbumsViewModel:

static let shared = AlbumsViewModel(albumService:favouritesService:recommendationService:) // however you initialise it

...then in CVC, refer to

AlbumsViewModel.shared

...or create a shortcut property

let viewModel = AlbumsViewModel.shared
Error -> init(coder:) has not been implemented
 
 
Q