Result Builder ایک Swift خصوصیت ہے جو پروٹوکول @resultBuilder کے ذریعے نافذ کی جاتی ہے، جو اظہارات کے تسلسل کو ایک مرکب قدر میں تبدیل کرتی ہے۔ مرتب کنندہ کنٹرول کنسٹرکٹس if، for، switch والے کوڈ بلاکس کو بلڈر کے جامد طریقوں — buildBlock، buildEither، buildArray — میں تبدیل کرتا ہے۔ Swift Evolution تجویز SE-0289 (2022) کے مطابق، result builders بیرونی پارسرز کے بغیر Swift کے اندر اعلانیہ DSL بنانے کی اجازت دیتے ہیں۔ سب سے مشہور مثال SwiftUI میں @ViewBuilder ہے، جہاں ویو کا باڈی اعلانیہ انداز میں مشروط اور تکراری عناصر سے بنایا جاتا ہے۔
خلاصہ
TupleView میں تبدیل کرتا ہےif/else، switch، for-in کو طریقوں buildOptional، buildEither، buildArray کے ذریعے سپورٹ کرتا ہےResult Builder (پہلے function builders کے نام سے جانا جاتا تھا) ایک Swift میکانزم ہے جو لائن بریک کے ذریعے جدا کردہ اظہارات کے تسلسل کو ایک واحد قدر میں تبدیل کرنے کی اجازت دیتا ہے۔ اسے @resultBuilder خصوصیت کا استعمال کرتے ہوئے اعلان کیا جاتا ہے جو ایک ساخت پر لاگو ہوتی ہے جو جامد تبدیلی کے طریقوں کو نافذ کرتی ہے۔
Result builders سے پہلے، SwiftUI body کا اعلانیہ نحو ناممکن تھا۔ ویوز کی کمپیکٹ فہرست کے بجائے، ڈویلپرز کو دستی طور پر TupleView کالز لکھنی پڑتی تھیں۔ Result Builder خود بخود ہر اظہار کو لپیٹتا ہے، شاخ بندی اور لوپس کو سپورٹ کرتا ہے، ڈویلپر سے ساخت کی پیچیدگی چھپاتا ہے۔
Swift Evolution SE-0289، 2022 میں منظور شدہ، کے مطابق result builder function builders (SE-0258، Swift 5.1) کے خیال کا ارتقا ہے۔ اہم تبدیلیاں: @_functionBuilder سے @resultBuilder میں نام تبدیل کرنا اور فنکشن پیرامیٹرز تک توسیع، جس سے بلڈر کو صرف ویو باڈی کے بجائے کسی بھی کلوزر آرگیومنٹ کے لیے استعمال کیا جا سکے۔
Result builders کا استعمال کریں جب آپ کو اپنی لائبریری کے صارفین کو پیچیدہ ڈھانچے — کنفیگریشنز، سوالات، UI اجزاء — بنانے کے لیے ایک اعلانیہ نحو فراہم کرنے کی ضرورت ہو، بغیر لازمی اسمبلی کوڈ لکھے۔
Swift مرتب کنندہ @resultBuilder سے نشان زدہ ہر کوڈ بلاک کو بلڈر کے جامد طریقوں کی کالز کے تسلسل میں تبدیل کرتا ہے۔ آئیے ایک سادہ بلڈر دیکھتے ہیں جو سٹرنگز کو جوڑتا ہے:
@resultBuilder
struct StringBuilder {
static func buildBlock(_ parts: String...) -> String {
parts.joined(separator: " ")
}
}
اس بلڈر کا استعمال — ہر سٹرنگ ایک علیحدہ لائن پر ایک اسپیس کے ساتھ جوڑی جاتی ہے:
@StringBuilder
func greeting() -> String {
"Hello"
"World"
"from"
"Swift"
}
// مرتب کنندہ اسے تبدیل کرتا ہے:
// StringBuilder.buildBlock("Hello", "World", "from", "Swift")
// نتیجہ: "Hello World from Swift"
مرتب کنندہ متواتر اظہارات کو گروپ کرتا ہے اور انہیں متغیر پیرامیٹرز کے طور پر buildBlock پر بھیجتا ہے۔ اگر اظہاروں کے درمیان if آتا ہے، تو مرتب کنندہ شاخ بندی کے لیے buildOptional یا buildEither کو کال کرتا ہے۔ for-in لوپس کے لیے یہ buildArray کو کال کرتا ہے۔ اس طرح عام Swift کوڈ کالز کی ایک زنجیر میں تبدیل ہو جاتا ہے جو حتمی قدر تشکیل دیتی ہے۔
ہر result builder جامد طریقوں کا ایک مجموعہ متعین کرتا ہے جسے مرتب کنندہ تبدیلی کے دوران کال کرتا ہے۔ اہم طریقے:
| طریقہ | مقصد | کب کال کیا جاتا ہے |
|---|---|---|
| buildBlock | اظہاروں کے تسلسل کو جوڑتا ہے | ہر بلاک کے لیے بغیر شاخ بندی کے |
| buildOptional | if کو بغیر else کے ہینڈل کرتا ہے | جب if بغیر else کے ہو |
| buildEither(first:) | if-else کی پہلی شاخ | if کے ساتھ else پر |
| buildEither(second:) | if-else کی دوسری شاخ | if کے ساتھ else پر |
| buildArray | for-in لوپس کو ہینڈل کرتا ہے | جب for-in موجود ہو |
| buildExpression | انفرادی اظہار کو تبدیل کرتا ہے | ہر اظہار کے لیے buildBlock میں بھیجنے سے پہلے |
| buildFinalResult | حتمی تبدیلی | کلوزر سے واپس آنے سے پہلے |
کم از کم نفاذ کے لیے صرف متغیر پیرامیٹرز کے ساتھ buildBlock کی ضرورت ہے — یہ شاخ بندی کے بغیر بلاکس کے لیے کافی ہے۔ buildOptional اور buildEither شامل کرنے سے مشروط ڈھانچے کی حمایت شامل ہوتی ہے، اور buildArray لوپس کے لیے۔ Swift دستاویزات (2025) کے مطابق، زیادہ سے زیادہ DSL لچک کے لیے تمام طریقوں کو نافذ کرنے کی سفارش کی جاتی ہے۔
buildExpression مختلف اقسام کے اظہاروں کو قبول کرنے اور انہیں ایک بلڈر قسم میں تبدیل کرنے کی اجازت دیتا ہے۔ مثال کے طور پر، @ViewBuilder میں، buildExpression Text، Image، Button کو قبول کرتا ہے اور انہیں مشترکہ View قسم میں تبدیل کرتا ہے۔
آئیے HTML سٹرنگز بنانے کے لیے بلڈر بنانے پر غور کریں۔ یہ DSL براہ راست Swift میں اعلانیہ HTML لکھنے کی اجازت دے گا:
@resultBuilder
enum HTMLBuilder {
static func buildBlock(_ components: String...) -> String {
components.joined()
}
static func buildOptional(_ component: String?) -> String {
component ?? ""
}
static func buildEither(first component: String) -> String {
component
}
static func buildEither(second component: String) -> String {
component
}
static func buildArray(_ components: [String]) -> String {
components.joined()
}
}
HTML بنانے کے لیے کسٹم بلڈر کا استعمال:
func div(@HTMLBuilder _ content: () -> String) -> String {
"<div>\(content())</div>"
}
func p(_ text: String) -> String {
"<p>\(text)</p>"
}
let page = div {
p("Hello")
p("World")
if showFooter {
p("فوٹر")
}
}
// نتیجہ: <div><p>Hello</p><p>World</p><p>Footer</p></div>
Swift.org (2025) کے مضمون “Building Custom Result Builders in Swift” کے مطابق، کسٹم بلڈر لائبریریوں میں کنفیگریشن فائلیں، UI اجزاء، ڈیٹا میپنگ، اور یہاں تک کہ ڈیٹا بیس سوالات بنانے کے لیے استعمال ہوتے ہیں — جہاں کہیں بھی شاخ بندی کی حمایت کے ساتھ اعلانیہ نحو کی ضرورت ہو۔
@ViewBuilder SwiftUI میں شامل ایک result builder ہے جو زیادہ تر کنٹینر ویوز کے content پیرامیٹر پر لاگو ہوتا ہے: VStack، HStack، ZStack، Group، List، اور خود body پراپرٹی۔ یہ کوما یا ریپر کے بغیر علیحدہ لائنوں پر متعدد ویوز لکھنے کی اجازت دیتا ہے۔
@ViewBuilder تمام result builder طریقوں کو نافذ کرتا ہے، بشمول if-else، switch، اور for-in کی حمایت۔ جب شرط درست ہوتی ہے، buildEither(first:) ایک ویو لوٹاتا ہے؛ جب غلط، buildEither(second:) دوسرا لوٹاتا ہے۔ دونوں شاخوں کو ایک ہی قسم لوٹانی چاہیے، لیکن SwiftUI اندرونی طور پر AnyView یا ConditionalContent کے ذریعے قسم مٹانے کا استعمال کرتا ہے۔
struct GreetingView: View {
let isLoggedIn: Bool
var body: some View {
VStack {
Image(systemName: "person.circle")
Text("پروفائل")
.font(.title)
if isLoggedIn {
Text("خوش آمدید!")
.foregroundColor(.green)
} else {
Button("لاگ ان کریں") { }
}
}
}
}
@ViewBuilder کے بغیر، اسی کوڈ کو ہر مشروط حصے کے لیے Group یا AnyView کے استعمال کی ضرورت ہوتی، جو کارکردگی کو خراب کرتا ہے۔ @ViewBuilder خود بخود ہر امتزاج کے لیے سب سے موثر نمائندگی — ConditionalContent یا TupleView — منتخب کرتا ہے۔
پہلی حد buildBlock میں اظہاروں کی زیادہ سے زیادہ تعداد ہے۔ Swift معیاری لائبریری 2–10 اظہاروں کے لیے buildBlock اوورلوڈز متعین کرتی ہے۔ اگر کسی بلاک میں 10 سے زیادہ اظہار ہوں، تو مرتب کنندہ ایک خرابی پیدا کرے گا۔ حل — ذیلی بلاکس میں تقسیم کرنے کے لیے Group یا VStack کے ذریعے گروپ کرنا۔
دوسری حد بلڈر بلاک کے اندر متغیرات اور تفویض کی حمایت کا فقدان ہے۔ @ViewBuilder کے اندر let x = 5 کا اعلان نہیں کیا جا سکتا۔ تمام اظہار ایسے اظہار ہونے چاہئیں جو بلڈر قسم کی قدر لوٹاتے ہیں۔ درمیانی حسابات کے لیے، بلڈر سے باہر حسابات یا مختلف اقسام کی حمایت کے ساتھ buildExpression استعمال کریں۔
تیسری حد ڈیبگنگ کی پیچیدگی ہے۔ Result builder کے اندر تالیف کی غلطیاں اکثر مبہم پیغامات دیتی ہیں، خاص طور پر جب if/else شاخوں میں اقسام مماثل نہ ہوں۔ ڈیبگنگ کے لیے واضح واپسی کی اقسام اور AnyView استعمال کریں، اگرچہ مؤخر الذکر کارکردگی کو کم کرتا ہے۔ Hacking with Swift (2025) کے مطابق، عملی مشورہ — شاخ بندی کے بغیر ایک سادہ بلڈر سے شروع کریں اور آہستہ آہستہ مشروط ڈھانچے کی حمایت شامل کریں۔
اکثر پوچھے گئے سوالات
Result Builder ایک Swift خصوصیت ہے جو جامد طریقوں کے ذریعے اظہاروں کے تسلسل کو نتیجہ قدر میں تبدیل کرتی ہے۔ یہ اعلانیہ DSL بنانے کی اجازت دیتا ہے، سب سے مشہور مثال SwiftUI میں @ViewBuilder ہے جو لازمی کوڈ کے بغیر ویو کا درجہ بندی بنانے کے لیے ہے۔
@resultBuilder خصوصیت والی ساخت کا اعلان کریں اور کم از کم buildBlock طریقہ نافذ کریں۔ شرائط کی حمایت کے لیے buildOptional اور buildEither شامل کریں؛ لوپس کے لیے buildArray شامل کریں۔ فنکشن میں کلوزر پیرامیٹر سے پہلے بلڈر خصوصیت استعمال کریں۔
صرف buildBlock لازمی ہے۔ دیگر تمام طریقے — buildOptional، buildEither، buildArray، buildExpression، buildFinalResult — اختیاری ہیں اور متعلقہ ڈھانچے کے لیے حمایت شامل کرتے ہیں۔ جتنے زیادہ طریقے نافذ کیے جائیں گے، DSL اتنا ہی لچکدار ہوگا۔
@ViewBuilder View پروٹوکول کے لیے result builder کا ایک ٹھوس نفاذ ہے۔ یہ SwiftUI میں @resultBuilder خصوصیت والی ساخت کے طور پر متعین ہے، جو مختلف تعداد میں ویوز کے لیے buildBlock طریقے (TupleView)، ConditionalContent کے لیے buildEither اور ForEach کے لیے buildArray فراہم کرتا ہے۔
ہاں، معیاری buildBlock اوورلوڈز 10 اظہاروں تک حمایت کرتے ہیں۔ اس سے تجاوز کرنے پر، ذیلی بلاکس میں تقسیم کرنے کے لیے nestڈ کنٹینر (Group, VStack) استعمال کریں۔ ایک کسٹم بلڈر بغیر کسی حد کے متغیر buildBlock متعین کر سکتا ہے۔
خلاصہ
buildBlock، buildEither، buildOptional، buildArray کی کالز سے بدل دیتا ہےہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں