I'm getting a segmentation fault when I try to compile the below code. I'm trying to make a type constrained extension on the CellUpdater
struct, which accesses a property whose type is defined on an associatedtype on a generic type. Not sure if I'm doing something wrong or if it's a limitation of the Swift compiler, any ideas?
protocol CellUpdaterType {
func generateDetailsDrillDownController(index: Int) -> UIViewController?
}
extension CellUpdaterType {
func generateDetailsDrillDownController(index: Int) -> UIViewController? { return nil }
}
struct CellUpdater<Cell where Cell: UpdatableView> : CellUpdaterType {
let viewModel: Cell.ViewModel
}
extension CellUpdater where Cell: HeadlineCell {
func generateDetailsDrillDownController(index: Int) -> UIViewController? {
let storyboard = UIStoryboard(name: "SomeStoryboard", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("SomeViewController") as? SomeViewController
vc?.headline = viewModel.headline // This line crashes the compiler
return vc
}
}
class HeadlineCell: UITableViewCell {
var headline: Headline?
// ...
}
extension HeadlineCell : UpdatableView {
typealias ViewModel = HeadlineCellViewModel
func update(viewModel viewModel: ViewModel) {
// ...
}
}
struct HeadlineCellViewModel {
let headline: Headline
init(headline: Headline) {
self.headline = headline
}
}
protocol UpdatableView: class {
associatedtype ViewModel
func update(viewModel viewModel: ViewModel)
}
I think it might be connected to compiler not being able to fix your view model type at compile time, which is required in Swift. It might have been fixed in Swift 3.0 though. I've manage to change your code a little so it now compiles. The major difference was to constraint view model instead of cell in CellUpdater extension.
struct CellUpdater<Cell where Cell: UpdatableView> : CellUpdaterType {
typealias ViewModel = Cell.ViewModel
let viewModel: ViewModel
}
extension CellUpdater where Cell.ViewModel : HeadlineCellViewModelType {
func generateDetailsDrillDownController(index: Int) -> UIViewController? {
let storyboard = UIStoryboard(name: "SomeStoryboard", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("SomeViewController") as? SomeViewController
vc?.headline = viewModel.headline
return vc
}
}
protocol HeadlineCellViewModelType {
var headline: Headline { get }
}
struct HeadlineCellViewModel : HeadlineCellViewModelType {
let headline: Headline
init(headline: Headline) {
self.headline = headline
}
}