# SwiftUI Previews and Generic Types That Implement Objective-C Protocols

**URL:** <https://forums.swift.org/t/swiftui-previews-and-generic-types-that-implement-objective-c-protocols/36926>\
**Category:** Using Swift\
**Tags:** generics, objective-c, xcode, uikit, swiftui\
**Created:** [May 27, 2020, 4:00pm UTC](https://forums.swift.org/t/swiftui-previews-and-generic-types-that-implement-objective-c-protocols/36926 "2020-05-27T16:00:41Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![SlaunchaMan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slaunchaman/32/520_2.png) [@SlaunchaMan](https://forums.swift.org/u/SlaunchaMan)\
**Post date:** [May 27, 2020, 4:00pm UTC](https://forums.swift.org/t/swiftui-previews-and-generic-types-that-implement-objective-c-protocols/36926/1 "2020-05-27T16:00:41Z")

</div>

I have a project that uses UIKit. In this project, I have a need to create multiple table views that look the same but represent different contents. Sounds like a great use case for generics! Here’s a basic view controller that achieves this:

```
import UIKit

class GenericTableViewController<ItemType>: UIViewController, UITableViewDataSource, UITableViewDelegate {

    weak var tableView: UITableView?

    var items: [ItemType] = [] {
        didSet {
            tableView?.reloadData()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let tableView = UITableView(frame: view.bounds)
        self.tableView = tableView
        view.addSubview(tableView)

        tableView.delegate = self
        tableView.dataSource = self
    }

    func numberOfSections(in tableView: UITableView) -> Int { 1 }

    func tableView(_ tableView: UITableView,
                   numberOfRowsInSection section: Int) -> Int {
        guard section == 0 else { return 0 }

        return items.count
    }

    func tableView(_ tableView: UITableView,
                   cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)

        cell.textLabel?.text = String(describing: items[indexPath.row])

        return cell
    }
    
}

```

Now, I’m also using @mattt’s excellent [Gist](https://gist.github.com/mattt/ff6b58af8576c798485b449269d43607) for previewing view controllers. The relevant bit is here:

```
import SwiftUI

@available(iOS 13.0, *)
struct UIViewControllerPreview<ViewController: UIViewController>: UIViewControllerRepresentable {
    let viewController: ViewController

    init(_ builder: @escaping () -> ViewController) {
        viewController = builder()
    }

    // MARK: - UIViewControllerRepresentable

    func makeUIViewController(context: Context) -> ViewController {
        viewController
    }

    func updateUIViewController(_ uiViewController: ViewController,
                                context: Context) {
        return
    }
}

```

Either one of these works great independently. I can create a sample project with the view controller and use it to display multiple values. However, if I try to use them _together_, Xcode fails to build the preview with the following error:

```
extensions of generic classes cannot contain '@objc' members

```

I’m not sure where the extension comes in, but looking at the diagnostics it looks like my code is being replaced dynamically at runtime with versions that have a ` __preview__ ` prefix:

```
/Users/jeff/Library/Developer/Xcode/DerivedData/GenericViewController-gppxxshymxycwxafswamwxroqimy/Build/Intermediates.noindex/Previews/GenericViewController/Intermediates.noindex/GenericViewController.build/Debug-iphonesimulator/GenericViewController.build/Objects-normal/x86_64/GenericViewController.2.preview-thunk.swift:23:72: error: extensions of generic classes cannot contain '@objc' members
@_dynamicReplacement(for: tableView(_:cellForRowAt:)) private func __preview__ tableView(_ tableView: UITableView,

```

This happens even if I adjust `UIViewControllerPreview` to not take a generic `ViewController` type and instead operate solely on `UIViewController`. Has anyone else run into this—and is there a way to prevent the SwiftUI preview system from dynamically replacing `@objc` methods like this in an extension?

---

<div class="post-metadata">

**Author:** ![SlaunchaMan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slaunchaman/32/520_2.png) [@SlaunchaMan](https://forums.swift.org/u/SlaunchaMan)\
**Post date:** [May 27, 2020, 4:03pm UTC](https://forums.swift.org/t/swiftui-previews-and-generic-types-that-implement-objective-c-protocols/36926/2 "2020-05-27T16:03:34Z")

</div>

Digging deeper, looking at the source file in the DerivedData file, we can see that the method is indeed overwritten by the preview but unchanged:

```swift
extension GenericTableViewController {
    @_dynamicReplacement(for: tableView(_:cellForRowAt:)) private func __preview__ tableView(_ tableView: UITableView,
                   cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        #sourceLocation(file: "/Users/jeff/Desktop/GenericViewController/GenericViewController/GenericViewController.swift", line: 43)
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)

        cell.textLabel?.text = String(describing: items[indexPath.row])

        return cell
#sourceLocation()
    }
}

```
