SwiftUI — WWDC 2019 میں پیش کیا گیا، Apple کے ایکو سسٹم کے تمام پلیٹ فارمز پر یوزر انٹرفیس بنانے کے لیے Apple کا اعلانیہ فریم ورک۔ لازمی UIKit اور اس کے viewDidLoad اور دستی اسکرین اپ ڈیٹس کے برعکس، SwiftUI UI کو View پروٹوکول کی پیروی کرنے والے سادہ ڈھانچوں کے مجموعہ کے طور پر بیان کرتا ہے۔ Swift.org (2025) کے مطابق، SwiftUI App Store پر شائع ہونے والے 65% نئے پروجیکٹس میں استعمال ہوتا ہے۔ فریم ورک State اور Data Flow میکانزم کے ذریعے خود بخود انٹرفیس اپ ڈیٹس کا انتظام کرتا ہے — جب ڈیٹا بدلتا ہے، View دستی reloadData کالز کے بغیر دوبارہ کھینچتا ہے۔
اہم نکات
SwiftUI — Apple کا اعلانیہ UI فریم ورک، جو UIKit سے یکسر مختلف ہے۔ کنٹرولرز، ویوز بنانے اور ان کے لائف سائیکل کو دستی طور پر منظم کرنے کے بجائے، ڈویلپر انٹرفیس کو اعلانات کے طور پر بیان کرتا ہے: اسکرین پر کیا ہونا چاہیے، نہ کہ اسے کیسے بنانا ہے۔ SwiftUI ردعمل کے اصول پر مبنی ہے: انٹرفیس حالت کا ایک فنکشن ہے۔ جب حالت بدلتی ہے، SwiftUI خود بخود تمام منحصر Views کے body کا دوبارہ حساب لگاتا ہے اور اسکرین کے صرف تبدیل شدہ حصوں کو اپ ڈیٹ کرتا ہے۔ SwiftUI iOS 13+، iPadOS 13+، macOS 10.15+، watchOS 6+، tvOS 13+ اور visionOS 1+ پر دستیاب ہے۔ SwiftUI کوڈ کراس پلیٹ فارم ہے: ایک فائل کم سے کم پلیٹ فارم موافقت کے ساتھ iPhone، iPad، Mac اور Apple Watch پر کام کرتی ہے۔ Apple WWDC Session 101 (2024) کے مطابق، SwiftUI App Store کے 90% سے زیادہ معیاری UI پیٹرن کو کور کرتا ہے۔
UIKit — لازمی فریم ورک (2008): ڈویلپر UIViewController بناتا ہے، viewDidLoad میں subviews کنفیگر کرتا ہے، UITableView کے لیے delegate/datasource لاگو کرتا ہے اور reloadData یا setNeedsLayout کے ذریعے اسکرین اپ ڈیٹ کرتا ہے۔ SwiftUI کنٹرولرز کو سادہ View ڈھانچوں، ڈیلیگیٹس کو bindings اور onChange، Auto Layout کو HStack/VStack/ZStack اور موڈیفائرز (padding، frame، offset) سے بدل دیتا ہے۔ UIKit کو ARC کے ذریعے دستی میموری مینجمنٹ کی ضرورت ہے؛ SwiftUI ڈھانچے استعمال کرتا ہے جنہیں ریفرنس کاؤنٹنگ کی ضرورت نہیں۔ SwiftUI کی کارکردگی UIKit کے برابر ہے: فریم ورک کم سے کم تبدیلی سیٹ کے لیے diffing الگورتھم استعمال کرتا ہے۔ IT Sectr میں، SwiftUI کا استعمال iOS 17+ ہدف والے نئے پروجیکٹس کے لیے کیا جاتا ہے؛ iOS 14–15 سپورٹ والے پروجیکٹس کو محدود SwiftUI مطابقت کی وجہ سے UIKit کی ضرورت ہوتی ہے۔
SwiftUI میں، انٹرفیس ViewBuilder — ایک result builder کے ذریعے بیان کیا جاتا ہے جو Views کے سیٹ کو tuple یا Group میں تبدیل کرتا ہے۔ موڈیفائرز (.padding()، .font()، .foregroundColor()) اصل آبجیکٹ کو تبدیل کرنے کے بجائے تبدیل شدہ سیٹنگز کے ساتھ نئی Views بناتے ہیں۔ ہر موڈیفائر ایک نئی View لوٹاتا ہے، جس سے زنجیر بنانا ممکن ہوتا ہے۔ ViewBuilder if/else، switch، ForEach کو سپورٹ کرتا ہے — علیحدہ کنٹرولرز کے بغیر مشروط اور چکراتی رینڈرنگ۔ SwiftUI میں View ایک value type (struct) ہے، جو پیش قیاسی رویے کو یقینی بناتا ہے اور race conditions کو ختم کرتا ہے۔
View — ایک پروٹوکول جس میں ایک ہی ضرورت ہے: some View قسم کی computed property body۔ View کی پیروی کرنے والا ہر ڈھانچہ body میں اسکرین کا اپنا حصہ بیان کرتا ہے۔ some View قسم ایک مبہم واپسی کی قسم ہے جو واپس کردہ View کی ٹھوس قسم کو چھپاتی ہے (VStack، HStack، ZStack، Text، Image وغیرہ کا اسٹیکنگ)۔ Swift کمپائلر کمپائل ٹائم پر ٹھوس قسم کا اندازہ لگاتا ہے، ٹائپ ایریزر کے بغیر براہ راست کالز کی کارکردگی کو برقرار رکھتا ہے۔
import SwiftUI
struct GreetingView: View {
var name: String
var body: some View {
VStack(spacing: 12) {
Text("ہیلو، \(name)!")
.font(.largeTitle)
.foregroundColor(.primary)
Text("SwiftUI میں خوش آمدید")
.font(.body)
.foregroundColor(.secondary)
}
.padding()
.background(
RoundedRectangle(cornerRadius: 12)
.fill(.ultraThinMaterial)
)
}
}GreetingView ڈھانچہ ایک name پیرامیٹر لیتا ہے اور عمودی اسٹیک میں دو ٹیکسٹ بلاکس دکھاتا ہے۔ موڈیفائرز .font، .foregroundColor، .padding اور .background ظاہری شکل کنفیگر کرتے ہیں۔ SwiftUI ہر بار جب ان پٹ پیرامیٹرز (name) بدلتے ہیں body کو کال کرتا ہے — دوبارہ کھینچنا صرف تبدیل شدہ حصوں کے لیے ہوتا ہے۔ مثال .ultraThinMaterial کے ساتھ RoundedRectangle استعمال کرتی ہے — SwiftUI میں شامل ایک نیٹو بلر بیک گراؤنڈ۔
@State — ایک property wrapper جو ایک ہی View سے تعلق رکھنے والی مقامی حالت کا اعلان کرتا ہے۔ SwiftUI خود بخود State میموری کا انتظام کرتا ہے: جب قدر بدلتی ہے، body دوبارہ کھینچتا ہے، لیکن صرف ان Views کے لیے جو اس State کو استعمال کرتی ہیں۔ State سادہ اقسام (String، Int، Bool، enum) کے لیے source of truth ہے۔ پیچیدہ ڈیٹا ماڈلز کے لیے @State استعمال نہ کریں — اس کے بجائے @StateObject اور @ObservedObject استعمال کریں۔ State پرائیویٹ ہونا چاہیے اور View کے اندر ہی ذخیرہ ہونا چاہیے، اجزاء کے درمیان منتقل نہیں ہونا چاہیے۔
import SwiftUI
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 20) {
Text("گنتی: \(count)")
.font(.system(size: 48, weight: .bold))
Button(action: { count += 1 }) {
Label("بڑھائیں", systemImage: "plus.circle")
}
.buttonStyle(.borderedProminent)
}
.padding()
}
}ابتدائی count قدر = 0۔ ہر بٹن دبانے سے count بڑھتا ہے؛ SwiftUI خود بخود پورے CounterView (تمام Views) کو دوبارہ کھینچتا ہے۔ UIKit میں، اسی طرح کے منظر نامے کے لیے IBOutlet، IBAction اور دستی label.text اپ ڈیٹس کی ضرورت ہوگی۔ @State یقینی بناتا ہے کہ View صرف اس وقت دوبارہ کھینچے جب کوئی مخصوص State بدلے — SwiftUI کا diffing الگورتھم درخت میں کم سے کم تبدیلیاں تلاش کرتا ہے۔
@Binding — ایک property wrapper جو View اور اس ڈیٹا کے درمیان دو طرفہ تعلق بناتا ہے جس کا View مالک نہیں ہے۔ Binding، State (یا source of truth دیگر) کا ایک حوالہ ہے، جو چائلڈ View کو والدین میں ذخیرہ شدہ قدر پڑھنے اور تبدیل کرنے کی اجازت دیتا ہے۔ Binding کو $ سابقہ سے ظاہر کیا جاتا ہے: $count چائلڈ View میں Binding<Int> منتقل کرتا ہے۔ Binding کے بغیر، چائلڈ View والدین کے ڈیٹا کو تبدیل نہیں کر سکتا — صرف پڑھ سکتا ہے۔
import SwiftUI
struct StepperControl: View {
@Binding var value: Int
let range: ClosedRange<Int>
var body: some View {
HStack {
Button(action: { if value > range.lowerBound { value -= 1 } }) {
Image(systemName: "minus.circle")
}
Text("\(value)")
.frame(minWidth: 40)
Button(action: { if value < range.upperBound { value += 1 } }) {
Image(systemName: "plus.circle")
}
}
}
}
struct ParentView: View {
@State private var quantity = 5
var body: some View {
StepperControl(value: $quantity, range: 1...10)
}
}ParentView State quantity کا مالک ہے اور $quantity کے ذریعے Binding منتقل کرتا ہے۔ StepperControl قدر تبدیل کر سکتا ہے، اور والدین میں quantity خود بخود مطابقت پذیر ہو جاتی ہے۔ Binding ڈیٹا کی کاپی نہیں ہے، بلکہ source of truth تک ایک پل ہے۔ حسب ضرورت کنٹرولز، ایڈیٹرز اور دوبارہ قابل استعمال اجزاء کے لیے @Binding استعمال کریں جنہیں والدین کے ڈیٹا کو تبدیل کرنے کی ضرورت ہے۔
@StateObject — ObservableObject کی پیروی کرنے والی کلاس کی مثال بنانے اور اس کا مالک ہونے کے لیے property wrapper۔ View لائف سائیکل میں ایک بار آبجیکٹ بناتی ہے اور اس کی @Published خصوصیات بدلنے پر دوبارہ کھینچتی ہے۔ @ObservedObject — ایک ایسا ہی ریپر، لیکن View آبجیکٹ کی مالک نہیں ہے — آبجیکٹ View کے باہر بنایا اور ذخیرہ کیا جاتا ہے (ایک انیشیالائزر کے ذریعے منتقل کیا جاتا ہے)۔ Apple View درجہ بندی میں source of truth کے لیے @StateObject اور انحصار انجیکشن کے لیے @ObservedObject تجویز کرتا ہے۔
import SwiftUI
import Combine
class UserSettings: ObservableObject {
@Published var username: String = "Guest"
@Published var isLoggedIn = false
}
struct ProfileView: View {
@StateObject private var settings = UserSettings()
var body: some View {
VStack {
TextField("Username", text: $settings.username)
.textFieldStyle(.roundedBorder)
Toggle("Logged In", isOn: $settings.isLoggedIn)
if settings.isLoggedIn {
Text("\(settings.username)، خوش آمدید!")
.font(.headline)
}
}
.padding()
}
}UserSettings — دو @Published خصوصیات کے ساتھ ایک ObservableObject۔ ProfileView @StateObject کے ذریعے آبجیکٹ کی مالک ہے۔ username یا isLoggedIn میں تبدیلی خود بخود ProfileView کو دوبارہ کھینچتی ہے۔ @Published SwiftUI کو تبدیلیوں سے آگاہ کرنے کے لیے Combine Publisher استعمال کرتا ہے۔ چائلڈ Views میں settings منتقل کرنے کے لیے @ObservedObject استعمال کریں:
Apple SwiftUI میں Data Flow کی چار سطحیں بیان کرتا ہے: @State (مقامی، value type)، @Binding (دو طرفہ)، @StateObject/@ObservedObject (ObservableObject کے ساتھ reference type)، @EnvironmentObject (عالمی، ماحول کے ذریعے انجیکٹ)۔ EnvironmentObject انیشیالائزر میں واضح منتقلی کے بغیر پورے View درجہ بندی میں ڈیٹا منتقل کرنے کی اجازت دیتا ہے۔ مزید برآں، @AppStorage UserDefaults کے ساتھ کام کرتا ہے، @SceneStorage سین کی حالت کے ساتھ، @FetchRequest Core Data کے ساتھ۔ Data Flow کی سطح کا انتخاب ایپلیکیشن آرکیٹیکچر کا تعین کرتا ہے: سادہ اسکرینیں State/Binding استعمال کرتی ہیں، ماڈیولر ObservedObject استعمال کرتی ہیں، بڑے پیمانے پر EnvironmentObject + Redux جیسے حل (TCA، Composable Architecture) استعمال کرتی ہیں۔
| Property Wrapper | ملکیت | قسم | کب استعمال کریں |
|---|---|---|---|
| @State | مقامی | Value (struct, enum) | ایک View کی سادہ حالت (کاؤنٹر، ٹوگل، ٹیکسٹ فیلڈ) |
| @Binding | بیرونی | State کا حوالہ | چائلڈ View والدین کے ڈیٹا کو تبدیل کر رہی ہے |
| @StateObject | View کی ملکیت | Reference (class) | پیچیدہ ڈیٹا ماڈل کے لیے source of truth |
| @ObservedObject | انجیکشن | Reference (class) | View کے باہر بنایا گیا ماڈل (init کے ذریعے منتقل) |
| @EnvironmentObject | عالمی | Reference (class) | پورے درجہ بندی کے لیے دستیاب ڈیٹا (auth، theme) |
اکثر پوچھے گئے سوالات
@State — value types (struct، enum، String، Int) اور ایک View کی مقامی حالت کے لیے۔ SwiftUI خود بخود State میموری کا انتظام کرتا ہے۔ @StateObject — ObservableObject کی پیروی کرنے والے reference types (class) کے لیے۔ @StateObject آبجیکٹ کا مالک ہے اور @Published خصوصیات بدلنے پر View کو دوبارہ کھینچتا ہے۔ سادہ کاؤنٹرز کے لیے @State استعمال کریں؛ کاروباری منطق والے ماڈلز کے لیے @StateObject استعمال کریں۔
ہاں، SwiftUI UIHostingController (UIKit کے اندر SwiftUI) اور UIViewRepresentable (SwiftUI کے اندر UIKit) کے ذریعے UIKit کے ساتھ ضم ہوتا ہے۔ UIHostingController SwiftUI View کو UIViewController میں لپیٹتا ہے۔ UIViewRepresentable SwiftUI میں UIKit اجزاء (MKMapView، WKWebView) استعمال کرنے کی اجازت دیتا ہے۔ UIKit سے SwiftUI میں پروجیکٹ منتقل کرنے کا یہ معیاری طریقہ ہے۔
ViewBuilder — ایک result builder (Swift 5.1) جو Views کے سیٹ کو TupleView، Group یا ConditionalContent قسم کی ایک قدر میں تبدیل کرتا ہے۔ ViewBuilder اعلانیہ body کے اندر لازمی if/else اور switch لکھنے کی اجازت دیتا ہے۔ ViewBuilder کے بغیر آپ کو ہر مشروط بلاک کے لیے AnyView یا Group لوٹانا ہوگا۔ ViewBuilder ہی وجہ ہے کہ body کو Views کے درمیان کوما کی ضرورت نہیں ہے۔
ہاں، SwiftUI iOS 13+، iPadOS 13+، macOS 10.15+، watchOS 6+، tvOS 13+ اور visionOS 1+ کو سپورٹ کرتا ہے۔ تاہم، کچھ APIs صرف نئے ورژنز پر دستیاب ہیں: مثال کے طور پر، navigationStack (iOS 16+)، Observable macro (iOS 17+)۔ پسماندہ مطابقت کے لیے #available اور UIKit موافقت استعمال کریں۔
Xcode Debug View Hierarchy موڈیفائرز اور فریموں کے ساتھ SwiftUI View کا درخت دکھاتا ہے۔ SwiftUI Inspector ٹول (Xcode دائیں پینل) ریئل ٹائم میں موڈیفائرز تبدیل کرنے کی اجازت دیتا ہے۔ body میں self._printChanges() دوبارہ کھینچنے کی وجوہات لاگ کرتا ہے۔ SwiftUI ٹیمپلیٹ کے ساتھ Instruments View کی کارکردگی کو ٹریس کرتا ہے اور ضرورت سے زیادہ دوبارہ کھینچنے کی نشاندہی کرتا ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔