PreviewProvider è un protocollo SwiftUI che definisce il punto di ingresso per generare anteprime in Xcode Canvas. L'implementazione del protocollo consente allo sviluppatore di vedere l'interfaccia senza avviare il simulatore, accelerando l'iterazione durante la fase di layout. Secondo la Apple Developer Documentation (2026), PreviewProvider è obbligatorio per tutte le SwiftUI View se il progetto utilizza Canvas — senza di esso, Canvas non visualizza l'interfaccia utente. Scopri di più nell'articolo su SwiftUI.
Punti chiave
PreviewProvider è un protocollo SwiftUI che definisce un contratto per creare contenuti di anteprima in Xcode Canvas. Il protocollo contiene un'unica proprietà obbligatoria: previews di tipo some View. Qualsiasi valore restituito da previews viene visualizzato in Canvas come anteprima interattiva. PreviewProvider non richiede ereditarietà — è sufficiente un'implementazione statica in un'estensione.
Architettonicamente, PreviewProvider non fa parte del runtime SwiftUI — è esclusivamente uno strumento di sviluppo. Il protocollo è contrassegnato con l'attributo @available(iOS 13.0, *) e non viene compilato nella build di rilascio, poiché Xcode utilizza la compilazione condizionale per escludere il codice di anteprima dalla produzione. Ciò significa che PreviewProvider non influisce sulle dimensioni del binario né sulle prestazioni dell'applicazione.
La proprietà previews è l'unico requisito di PreviewProvider. Deve restituire qualsiasi View: da un semplice Text a una gerarchia complessa con Group e ForEach. Xcode renderizza la View restituita in Canvas, applicando le impostazioni di sistema (tema, dimensione, carattere).
import SwiftUI
struct GreetingView: View {
let name: String
var body: some View {
Text("Hello, \(name)!")
.padding()
}
}
// PreviewProvider — static implementation
struct GreetingView_Previews: PreviewProvider {
static var previews: some View {
GreetingView(name: "World")
}
}
Convenzione di denominazione: Apple consiglia di denominare la struttura di anteprima come {ViewName}_Previews. Non è un requisito del compilatore, ma migliora la leggibilità e la navigazione del progetto. Xcode inserisce automaticamente questo modello quando crea un nuovo file SwiftUI.
Il meccanismo di funzionamento di PreviewProvider si basa sull'invio statico: Xcode compila l'estensione PreviewProvider solo per la configurazione Debug e chiama previews durante il processo di costruzione di Canvas. Ogni volta che il codice cambia, Xcode ricompila solo i PreviewProvider modificati, garantendo aggiornamenti quasi istantanei dell'anteprima.
SwiftUI non garantisce una corrispondenza esatta tra l'anteprima e l'interfaccia finale su un simulatore o dispositivo — Canvas utilizza un rendering semplificato. Le animazioni con ritardi potrebbero essere visualizzate in modo errato e alcuni componenti UIKit (MapKit, WebView) non vengono renderizzati in Canvas senza configurazione aggiuntiva.
Group consente di visualizzare più stati di una stessa View simultaneamente, accelerando l'iterazione durante la creazione di diverse configurazioni. Ogni anteprima all'interno di Group viene renderizzata indipendentemente.
struct ButtonView_Previews: PreviewProvider {
static var previews: some View {
Group {
ButtonView(title: "Primary", style: .primary)
.previewDisplayName("Primary")
ButtonView(title: "Disabled", style: .primary)
.disabled(true)
.previewDisplayName("Disabled")
ButtonView(title: "Secondary", style: .secondary)
.previewDisplayName("Secondary")
}
}
}
previewDisplayName aggiunge un'etichetta a ciascuna anteprima in Canvas, particolarmente utile quando si confrontano più stati. Il numero massimo di anteprime in Group non è limitato, ma più di 6–8 rallentano Canvas.
Xcode fornisce diversi modificatori per configurare la visualizzazione delle anteprime. I principali: previewDevice — emula un dispositivo specifico (iPhone 16 Pro, iPad Air, Apple Watch Ultra), previewLayout — imposta la dimensione (device, fixed, sizeThatFits). La combinazione di questi modificatori offre il controllo completo sull'ambiente di anteprima.
previewDevice accetta una stringa con il nome del dispositivo, ad esempio "iPhone 16 Pro" o "iPad Pro 13-inch (M4)". L'elenco dei dispositivi disponibili dipende dai simulatori installati in Xcode. Se il dispositivo non viene trovato, Canvas visualizza l'anteprima sul dispositivo predefinito senza errori.
| Modificatore | Descrizione | Esempio |
|---|---|---|
| previewDevice | Emulazione dispositivo | .previewDevice("iPhone 16 Pro") |
| previewLayout | Modalità dimensione | .previewLayout(.sizeThatFits) |
| previewDisplayName | Etichetta anteprima | .previewDisplayName("Dark Mode") |
| preferredColorScheme | Schema colori | .preferredColorScheme(.dark) |
| dynamicTypeSize | Dimensione carattere | .dynamicTypeSize(.xxxLarge) |
Pratica comune è mostrare una stessa View su più dispositivi contemporaneamente per verificare l'adattabilità. A questo scopo, si utilizza ForEach con un array di nomi di dispositivi.
struct AdaptiveView_Previews: PreviewProvider {
static var previews: some View {
ForEach(["iPhone SE (3rd generation)", "iPhone 16 Pro Max", "iPad Pro 13-inch (M4)"], id: \.self) { device in
AdaptiveView()
.previewDevice(.previewDevice(device))
.previewDisplayName(device)
}
}
}
Esempi pratici mostrano vari scenari di utilizzo di PreviewProvider: da anteprime semplici a configurazioni complesse con dati live e compatibilità UIKit.
I dati mock sono un pattern standard per le anteprime quando una View accetta un modello. Invece di una vera API, vengono sostituiti dati di test, consentendo la verifica visiva dello stato dell'interfaccia senza avviare l'applicazione.
struct UserProfileView: View {
let user: User
var body: some View {
VStack {
AsyncImage(url: user.avatarURL)
.clipShape(Circle())
Text(user.name)
.font(.title)
Text(user.bio)
.font(.body)
.foregroundColor(.secondary)
}
}
}
struct UserProfileView_Previews: PreviewProvider {
static var previews: some View {
UserProfileView(user: .mock)
.previewDisplayName("Profile")
UserProfileView(user: .mockLongName)
.previewDisplayName("Long Name")
}
}
Compatibilità UIKit — PreviewProvider funziona anche con componenti UIKit incapsulati in UIViewRepresentable. Ciò consente di visualizzare in anteprima viste UIKit esistenti in SwiftUI Canvas senza migrare l'intero progetto.
struct MapViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView()
}
func updateUIView(_ uiView: MKMapView, context: Context) {
// Configure map
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapViewRepresentable()
}
}
Canvas è l'editor visivo di Xcode che renderizza l'output di PreviewProvider in tempo reale. Senza un'implementazione di PreviewProvider, Canvas rimane vuoto. Canvas e PreviewProvider funzionano in coppia: PreviewProvider definisce cosa mostrare, Canvas definisce dove e come.
È importante capire: Canvas è l'ambiente di esecuzione dell'anteprima, non un'alternativa a PreviewProvider. Anche se lo sviluppatore non apre Canvas, PreviewProvider può essere utilizzato per una rapida verifica del codice tramite l'anteprima popup al passaggio del mouse sull'icona di Canvas. Secondo la WWDC 2024, Apple consiglia di scrivere PreviewProvider per ogni View come standard di sviluppo, analogamente alla scrittura di test unitari.
| Componente | Ruolo | Obbligatorietà |
|---|---|---|
| PreviewProvider | Definisce il contenuto dell'anteprima | Obbligatorio per Canvas |
| Canvas | Renderizza l'anteprima nell'editor | Opzionale (si può usare .preview) |
| SwiftUI View | Componente dell'interfaccia | Obbligatorio |
Raccomandazione: scrivi PreviewProvider per ogni View pubblica nel progetto. Questo accelera l'onboarding dei nuovi sviluppatori, semplifica le revisioni del codice e consente di verificare rapidamente le modifiche visive senza compilare l'intero progetto.
Problema 1: L'anteprima non si aggiorna. Se Canvas non riflette le modifiche al codice, la causa è solitamente la cache DerivedData. Pulisci DerivedData tramite Product → Clean Build Folder (⇧⌘K) o eliminando manualmente la cartella ~/Library/Developer/Xcode/DerivedData. Dopo la pulizia, Canvas ricostruisce l'anteprima da zero.
Problema 2: PreviewProvider non vede @StateObject. PreviewProvider crea un'istanza statica della View, quindi le dipendenze che richiedono iniezione (ViewModel, servizi) devono essere passate tramite l'inizializzatore o @StateObject con un valore predefinito. Utilizza oggetti mock invece di servizi reali nelle anteprime.
Problema 3: Le animazioni non funzionano in Canvas. Canvas non supporta tutte le animazioni SwiftUI — specialmente quelle che dipendono dal tempo (withAnimation con ritardo, .spring). Per testare le animazioni, esegui l'applicazione su un simulatore. Canvas è adatto per la verifica statica del layout.
L'iniezione di dipendenze è il modo migliore per far funzionare PreviewProvider con ViewModel complessi. Crea un'istanza separata di ViewModel con dati di test e passala all'inizializzatore della View.
struct DashboardView: View {
@StateObject var viewModel: DashboardViewModel
var body: some View {
List(viewModel.items) { item in
Text(item.title)
}
}
}
struct DashboardView_Previews: PreviewProvider {
static var previews: some View {
DashboardView(viewModel: DashboardViewModel.mock)
}
}
Estensioni mock: crea un'estensione per il ViewModel che fornisce istanze .mock statiche. Questo mantiene i dati di test vicini al ViewModel e rende PreviewProvider leggibile.
Domande frequenti
Tecnicamente no — l'applicazione si compilerà anche senza PreviewProvider. Tuttavia, nella pratica, Apple e la community SwiftUI raccomandano di scrivere anteprime per ogni View pubblica. PreviewProvider accelera lo sviluppo, consente di verificare rapidamente il layout su diversi dispositivi e funge da documentazione visiva per il team.
PreviewProvider aggiunge codice solo nelle build Debug, quindi possono verificarsi errori di compilazione se l'anteprima utilizza tipi non disponibili nella configurazione di rilascio. Si verificano errori anche quando si utilizza @available con piattaforme che non supportano Canvas, o quando si supera il limite di complessità dell'anteprima.
Direttamente — non è possibile, PreviewProvider viene eseguito in isolamento. Utilizza dati mock: crea un'estensione statica del modello con istanze .mock. Per le View con @StateObject, passa un ViewModel con dati di test tramite l'inizializzatore. Questo simula dati reali senza richieste di rete.
No, PreviewProvider non influisce sulla dimensione del binario di rilascio. Xcode utilizza la compilazione condizionale (#if DEBUG / #if !RELEASE) per escludere il codice di anteprima dalle build di rilascio. Il codice PreviewProvider esiste solo nella configurazione Debug e non finisce nelle build dell'App Store.
Sì, Xcode supporta il debug delle anteprime. Imposta un breakpoint all'interno di previews o del codice della View stessa e seleziona Product → Preview → Debug Preview. Il breakpoint scatterà durante il rendering di Canvas. Questo è utile per analizzare problemi di layout visibili solo nelle anteprime.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche