PreviewProvider — پروتکل SwiftUI که نقطه ورود برای تولید پیشنمایشها در Xcode Canvas را تعریف میکند. پیادهسازی پروتکل به توسعهدهنده اجازه میدهد بدون راهاندازی شبیهساز، رابط کاربری را ببیند و تکرار در مرحله طراحی را تسریع میکند. طبق Apple Developer Documentation (2026)، اگر پروژه از Canvas استفاده کند، PreviewProvider برای همه SwiftUI View الزامی است — بدون آن Canvas رابط کاربری را نمایش نمیدهد. بیشتر در مقاله SwiftUI بیاموزید.
نکات اصلی
PreviewProvider — پروتکل SwiftUI که قراردادی برای ایجاد محتوای پیشنمایش در Xcode Canvas تعریف میکند. پروتکل دارای یک ویژگی اجباری است: previews از نوع some View. هر مقداری که توسط previews برگردانده شود، در Canvas به عنوان یک پیشنمایش تعاملی نمایش داده میشود. PreviewProvider نیاز به ارثبری ندارد — یک پیادهسازی استاتیک در extension کافی است.
از نظر معماری، PreviewProvider بخشی از زمان اجرای SwiftUI نیست — این صرفاً یک ابزار توسعه است. پروتکل با ویژگی @available(iOS 13.0, *) مشخص شده و در بیلد release کامپایل نمیشود، زیرا Xcode از کامپایل شرطی برای حذف کد پیشنمایش از production استفاده میکند. این بدان معناست که PreviewProvider بر اندازه باینری و عملکرد برنامه تأثیر نمیگذارد.
ویژگی previews — تنها الزام PreviewProvider است. باید هر Viewای را برگرداند: از Text ساده تا سلسلهمراتب پیچیده با Group و ForEach. Xcode View برگشتی را در Canvas با اعمال تنظیمات سیستم (تم، اندازه، فونت) رندر میکند.
import SwiftUI
struct GreetingView: View {
let name: String
var body: some View {
Text("سلام، \(name)!")
.padding()
}
}
// PreviewProvider — پیادهسازی استاتیک
struct GreetingView_Previews: PreviewProvider {
static var previews: some View {
GreetingView(name: "World")
}
}
قرارداد نامگذاری: Apple توصیه میکند ساختار پیشنمایش را به صورت {ViewName}_Previews نامگذاری کنید. این یک الزام کامپایلر نیست، اما خوانایی و ناوبری در پروژه را بهبود میبخشد. Xcode هنگام ایجاد یک فایل SwiftUI جدید، این الگو را به طور خودکار جایگزین میکند.
مکانیسم کار PreviewProvider بر اساس ارسال استاتیک است: Xcode extension حاوی PreviewProvider را فقط برای پیکربندی Debug کامپایل میکند و previews را در فرآیند ساخت Canvas فراخوانی میکند. هر بار که کد تغییر میکند، Xcode فقط PreviewProviderهای تغییر یافته را دوباره کامپایل میکند که بهروزرسانی تقریباً آنی پیشنمایش را تضمین میکند.
SwiftUI تطابق دقیق پیشنمایش با UI نهایی روی شبیهساز یا دستگاه را تضمین نمیکند — Canvas از رندر سادهشده استفاده میکند. انیمیشنهای با تأخیر ممکن است به درستی نمایش داده نشوند و برخی از کامپوننتهای UIKit (MapKit، WebView) بدون تنظیمات اضافی در Canvas رندر نمیشوند.
Group امکان نمایش همزمان چند حالت از یک View را فراهم میکند که تکرار در طراحی پیکربندیهای مختلف را تسریع میکند. هر پیشنمایش درون Group به طور مستقل رندر میشود.
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 به هر پیشنمایش در Canvas برچسب اضافه میکند که به ویژه هنگام مقایسه چندین حالت مفید است. حداکثر تعداد پیشنمایشها در Group محدود نیست، اما بیش از 6–8 عدد Canvas را کند میکند.
Xcode ارائه میدهد چندین modifier برای پیکربندی نمایش پیشنمایش. موارد اصلی: previewDevice — دستگاه خاصی را شبیهسازی میکند (iPhone 16 Pro، iPad Air، Apple Watch Ultra)، previewLayout — اندازه را تعیین میکند (device، fixed، sizeThatFits). ترکیب این modifierها کنترل کامل بر محیط پیشنمایش میدهد.
previewDevice یک رشته با نام دستگاه دریافت میکند، مثلاً «iPhone 16 Pro» یا «iPad Pro 13-inch (M4)». لیست دستگاههای موجود به شبیهسازهای نصب شده در Xcode بستگی دارد. اگر دستگاه پیدا نشود، Canvas پیشنمایش را روی دستگاه پیشفرض بدون خطا نمایش میدهد.
| Modifier | توضیح | مثال |
|---|---|---|
| previewDevice | شبیهسازی دستگاه | .previewDevice(«iPhone 16 Pro») |
| previewLayout | حالت اندازه | .previewLayout(.sizeThatFits) |
| previewDisplayName | برچسب پیشنمایش | .previewDisplayName(«Dark Mode») |
| preferredColorScheme | تم طراحی | .preferredColorScheme(.dark) |
| dynamicTypeSize | اندازه فونت | .dynamicTypeSize(.xxxLarge) |
روش رایج — نمایش یک View روی چندین دستگاه به طور همزمان برای بررسی تطبیقپذیری. برای این کار از ForEach با آرایهای از نام دستگاهها استفاده میشود.
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)
}
}
}
نمونههای عملی سناریوهای مختلف استفاده از PreviewProvider را نشان میدهند: از پیشنمایش ساده تا پیکربندیهای پیچیده با دادههای زنده و سازگاری UIKit.
دادههای ساختگی — الگوی استاندارد برای پیشنمایش زمانی که View یک مدل دریافت میکند. به جای API واقعی، دادههای آزمایشی جایگزین میشوند که امکان بررسی بصری وضعیت UI بدون راهاندازی برنامه را فراهم میکند.
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")
}
}
سازگاری با UIKit — PreviewProvider با کامپوننتهای UIKit که در UIViewRepresentable پیچیده شدهاند نیز کار میکند. این امکان پیشنمایش Viewهای UIKit موجود در SwiftUI Canvas را بدون مهاجرت کل پروژه فراهم میکند.
struct MapViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView()
}
func updateUIView(_ uiView: MKMapView, context: Context) {
// پیکربندی نقشه
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapViewRepresentable()
}
}
Canvas — ویرایشگر بصری Xcode است که نتیجه PreviewProvider را در زمان واقعی رندر میکند. بدون پیادهسازی PreviewProvider، Canvas خالی میماند. Canvas و PreviewProvider به صورت جفت کار میکنند: PreviewProvider مشخص میکند چه چیزی نشان داده شود، Canvas — کجا و چگونه.
مهم است بدانید: Canvas — محیط اجرای پیشنمایش است، نه جایگزینی برای PreviewProvider. حتی اگر توسعهدهنده Canvas را باز نکند، PreviewProvider میتواند برای بررسی سریع کد از طریق پیشنمایش هنگام هاور روی آیکون Canvas استفاده شود. طبق WWDC 2024، Apple نوشتن PreviewProvider برای هر View را به عنوان استاندارد توسعه، مشابه نوشتن تستهای واحد توصیه میکند.
| کامپوننت | نقش | اجباری بودن |
|---|---|---|
| PreviewProvider | محتوای پیشنمایش را تعیین میکند | برای Canvas اجباری |
| Canvas | پیشنمایش را در ویرایشگر رندر میکند | اختیاری (میتوان از .preview استفاده کرد) |
| SwiftUI View | کامپوننت UI | اجباری |
توصیه: برای هر View عمومی در پروژه PreviewProvider بنویسید. این کار سرعت راهاندازی توسعهدهندگان جدید را افزایش میدهد، بازبینی کد را ساده میکند و امکان بررسی سریع تغییرات بصری بدون ساخت کل پروژه را فراهم میکند.
مشکل 1: پیشنمایش بهروز نمیشود. اگر Canvas تغییرات کد را منعکس نمیکند، دلیل اغلب کش DerivedData است. DerivedData را از طریق Product → Clean Build Folder (⇧⌘K) یا با حذف دستی پوشه ~/Library/Developer/Xcode/DerivedData پاک کنید. پس از پاکسازی، Canvas پیشنمایش را از نو میسازد.
مشکل 2: PreviewProvider @StateObject را نمیبیند. PreviewProvider یک نمونه استاتیک از View ایجاد میکند، بنابراین وابستگیهایی که نیاز به تزریق دارند (ViewModel، سرویسها) باید از طریق init یا @StateObject با مقدار پیشفرض منتقل شوند. در پیشنمایش به جای سرویسهای واقعی از اشیاء ساختگی استفاده کنید.
مشکل 3: انیمیشنها در Canvas کار نمیکنند. Canvas از همه انیمیشنهای SwiftUI پشتیبانی نمیکند — به ویژه آنهایی که به زمان وابسته هستند (withAnimation با تأخیر، .spring). برای بررسی انیمیشنها برنامه را روی شبیهساز اجرا کنید. Canvas برای بررسی استاتیک layout مناسب است.
تزریق وابستگی — بهترین راه برای کار کردن PreviewProvider با ViewModelهای پیچیده. یک نمونه جداگانه از ViewModel با دادههای آزمایشی ایجاد کنید و آن را به init ویو منتقل کنید.
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)
}
}
اکستنشنهای ساختگی: یک extension برای ViewModel ایجاد کنید که نمونههای استاتیک .mock را ارائه میدهد. این کار دادههای آزمایشی را در کنار ViewModel نگه میدارد و PreviewProvider را خوانا میکند.
سوالات متداول
از نظر فنی خیر — برنامه بدون PreviewProvider هم کامپایل میشود. اما در عمل Apple و جامعه SwiftUI توصیه میکنند برای هر View عمومی پیشنمایش بنویسید. PreviewProvider توسعه را سرعت میبخشد، امکان بررسی سریع layout در دستگاههای مختلف را فراهم میکند و به عنوان مستندات بصری برای تیم عمل میکند.
PreviewProvider کد را فقط به بیلد Debug اضافه میکند، بنابراین خطاهای کامپایل ممکن است زمانی رخ دهند که در پیشنمایش از انواعی استفاده شود که در پیکربندی release در دسترس نیستند. همچنین خطاها هنگام استفاده از @available با پلتفرمهایی که از Canvas پشتیبانی نمیکنند یا هنگام فراتر رفتن از محدودیت پیچیدگی پیشنمایش رخ میدهند.
مستقیماً — به هیچ وجه، PreviewProvider در انزوا اجرا میشود. از دادههای ساختگی استفاده کنید: یک extension استاتیک از مدل با نمونههای .mock ایجاد کنید. برای View با @StateObject، ViewModel را با دادههای آزمایشی از طریق init منتقل کنید. این کار دادههای واقعی را بدون درخواست شبکه شبیهسازی میکند.
خیر، PreviewProvider بر اندازه باینری release تأثیر نمیگذارد. Xcode از کامپایل شرطی (#if DEBUG / #if !RELEASE) برای حذف کد پیشنمایش از بیلد release استفاده میکند. کد PreviewProvider فقط در پیکربندی Debug وجود دارد و وارد بیلد App Store نمیشود.
بله، Xcode از دیباگ پیشنمایشها پشتیبانی میکند. داخل previews یا خود کد View breakpoint قرار دهید و Product → Preview → Debug Preview را انتخاب کنید. پس از آن breakpoint هنگام رندر Canvas فعال میشود. این برای تحلیل مشکلات layout که فقط در پیشنمایش قابل مشاهده هستند مفید است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید