How to create an extension for #Preview in SwiftUI

I wanted to do something like this with the new #preview macro in SwiftUI,

New way of Preview :thinking:

#Preview {
  CoinDetailView(coin: dev.coin) //👈 *This gives me error* ❌
}

<----------------------------------------------------------------------------------------->

The old way of preview :point_down:

struct CoinDetailView: View {
  let coin: CoinModel

  var body: some View {
    Text(coin.name)
  }
}
struct CoinDetailView_Previews: PreviewProvider {
    static var previews: some View {
        CoinDetailView(coin: dev.coin) // look at how clean that is 🌟
    }
}
//DI Container
class DeveloperPreview {
    static let shared = DeveloperPreview()
    private init() {}
    
    let coin = CoinModel(
        id: "bitcoin",
        symbol: "btc",
        name: "Bitcoin",
        image: "https://assets.coingecko.com/coins/images/1/large/bitcoin.png?1547033579",
        currentPrice: 61408,
        marketCap: 1141731099010)
}


// extend PreviewProvider with a computed property of our DI container
extension PreviewProvider {
  static var dev: DeveloperPreview {
      return DeveloperPreview.shared
  }
}

I would love to be proven wrong, but I don't think you can. If you right-click on the #Preview macro and click 'Expand Macro' you'll see the generated code. The struct that's generated has some kind of mangled name. Even if you try creating an extension using that name, the compiler won't let you, so I think you're out of luck.
But luckily, the old, but still good way of making preview structs still works.

But the generated struct conforms to a protocol, DeveloperToolsSupport.PreviewRegistry, so you could extend that protocol. I'm not sure it's exactly a stable API (though it shows up in the documentation, so maybe). Since this isn't something you'd be shipping, that shouldn't matter.

1 Like