0Pricing
Swift Academy · درس

المخزن وتكامل SwiftUI

حرّك العروض انطلاقًا من مخزن TCA.

المخزن وتكامل SwiftUI درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.

ما هو Store؟

إن Store هو الكائن أثناء التشغيل الذي يحتفظ بحالة الميزة ويشغّل الـ reducer الخاص بها. تراقب العروض في SwiftUI الـ store لقراءة الحالة، وترسل إليه الإجراءات لتحفيز التغييرات.

يمثل الـ store الجسر بين منطق الـ reducer النقي وواجهة المستخدم الحية التفاعلية.

import ComposableArchitecture
import SwiftUI

// A Store holds State, runs the Reducer,
// and is observed by SwiftUI views.

الاسم المستعار للنوع StoreOf

إن StoreOf<Feature> اسم مستعار ملائم لـ store مخصص لأنواع الحالة والإجراءات الخاصة بميزة معينة. تحتفظ العروض عادةً بواحد منه كخاصية مخزّنة.

لذلك يخزّن عرض العداد قيمة من النوع StoreOf<CounterFeature>.

import ComposableArchitecture
import SwiftUI

struct CounterView: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        Text("Count: \(store.count)")
    }
}

إنشاء Store

تنشئون store باستخدام مُهيئ Store، مع تقديم الحالة الابتدائية والـ reducer الذي سيُشغَّل. يُجرى ذلك عادةً مرة واحدة بالقرب من نقطة دخول التطبيق.

تعيد الدالة اللاحقة نسخة من ميزتكم.

import ComposableArchitecture
import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            CounterView(
                store: Store(initialState: CounterFeature.State()) {
                    CounterFeature()
                }
            )
        }
    }
}

قراءة الحالة مباشرةً

مع المراقبة الحديثة، يقرأ العرض الحالة مباشرةً من store باستخدام صيغة النقطة، مثل store.count. وبما أن الحالة تحمل @ObservableState، يعيد SwiftUI عرض الأجزاء التي تعتمد على القيم المتغيرة فقط.

لا حاجة إلى غلاف إضافي للقراءات البسيطة.

import ComposableArchitecture
import SwiftUI

struct CounterView: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        VStack {
            Text("Count: \(store.count)")
        }
    }
}

إرسال الإجراءات

لتغيير الحالة، يرسل العرض إجراءً باستخدام store.send(.someAction). يمرّر store الإجراء إلى الـ reducer، الذي يغيّر الحالة وقد يبدأ تأثيرات.

ترسل الأزرار هنا إجراءات الزيادة والنقصان.

import ComposableArchitecture
import SwiftUI

struct CounterView: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        HStack {
            Button("-") { store.send(.decrementTapped) }
            Text("\(store.count)")
            Button("+") { store.send(.incrementTapped) }
        }
    }
}

الربط من Store

بالنسبة إلى عناصر تحكم SwiftUI التي تحتاج إلى عمليات ربط ثنائية الاتجاه، يتيح لكم TCA اشتقاق Binding من store عندما تستخدم الحالة إجراءات قابلة للربط. يحدّث عنصر التحكم الحالة بإرسال إجراء ربط.

يرتبط TextField هنا بحقل اسم.

import ComposableArchitecture
import SwiftUI

struct FormView: View {
    @Bindable var store: StoreOf<FormFeature>
    var body: some View {
        TextField("Name", text: $store.name)
    }
}

WithViewStore القديم

قبل ظهور المراقبة، كانت العروض تغلّف واجهة المستخدم الخاصة بها داخل WithViewStore لقراءة الحالة والحصول على viewStore لإرسال الإجراءات. ستظلّون ترون ذلك في الشيفرة الأقدم.

تحدد دالة الإغلاق observe الحالة التي يعتمد عليها العرض.

import ComposableArchitecture
import SwiftUI

struct LegacyCounter: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        WithViewStore(store, observe: { $0 }) { viewStore in
            Text("Count: \(viewStore.count)")
        }
    }
}

اختيار ما تجب مراقبته

في الأسلوب القديم، تضيق دالة الإغلاق observe نطاق الحالة التي يراقبها العرض، لذلك يعيد العرض نفسه فقط عند تغيّر تلك القيم. تُعد مراقبة الحالة بأكملها أبسط، بينما تحسّن مراقبة مجموعة فرعية أداء العروض الكبيرة.

يتولى @ObservableState الحديث ذلك تلقائيًا، لكن فهم observe يساعدكم عند قراءة الشيفرة القديمة.

import ComposableArchitecture
import SwiftUI

// Observe just the count to limit re-renders:
WithViewStore(store, observe: { $0.count }) { viewStore in
    Text("\(viewStore)")
}

إرسال إجراءات مع حمولات

تُرسل الإجراءات التي تحمل قيمًا مرتبطة من خلال تمرير القيمة. هكذا يمرر العرض إدخال المستخدم الذي يحتاج إليه الـ reducer.

يرسل اختيار صف هنا المعرّف الذي اختاره المستخدم.

import ComposableArchitecture
import SwiftUI

struct ListView: View {
    let store: StoreOf<ListFeature>
    var body: some View {
        Button("Pick 42") {
            store.send(.rowSelected(id: 42))
        }
    }
}

تحريك الإجراءات

يمكنكم إرفاق حركة بإجراء مُرسل، بحيث يتحرك تغيير الحالة الناتج. مرّروا وسيط animation إلى send.

يبقي ذلك اعتبارات الحركة في موضع الاستدعاء، بينما تظل الحالة بيانات عادية.

import ComposableArchitecture
import SwiftUI

Button("Toggle") {
    store.send(.toggleTapped, animation: .default)
}

تركيب العرض

يحتفظ عرض TCA المكتمل بـ StoreOf، ويقرأ الحالة باستخدام صيغة النقطة، ويرسل الإجراءات من عناصر التحكم. يتولى الـ reducer بقية العمل، مما يحافظ على كون العرض بسيطًا وتصريحيًا.

هذا الفصل هو ما يجعل عروض TCA سهلة القراءة والمعاينة.

import ComposableArchitecture
import SwiftUI

struct CounterView: View {
    let store: StoreOf<CounterFeature>
    var body: some View {
        VStack {
            Text("Count: \(store.count)")
            Button("Increment") { store.send(.incrementTapped) }
        }
    }
}

فحص سريع: تشغيل واجهة المستخدم

استذكروا كيف يحرّك عرض SwiftUI تغييرًا في الحالة ضمن TCA.

خلاصة: Store وSwiftUI

ربطتم ميزةً بـ SwiftUI:

  • يحتفظ StoreOf<Feature> بالحالة ويشغّل الـ reducer.
  • تنشئون store باستخدام حالة ابتدائية وreducer الميزة.
  • تتيح المراقبة الحديثة قراءة الحالة بصيغة النقطة، مثل store.count.
  • تغيّر العروض الحالة باستدعاء store.send(.action)، مع إمكانية تمرير حمولة أو حركة.
  • يظهر WithViewStore القديم ودالة الإغلاق observe الخاصة به في الشيفرة الأقدم.

ستزوّدون الـ reducer بعد ذلك بتأثيرات جانبية وتبعيات قابلة للحقن.

import ComposableArchitecture
import SwiftUI

// Recap: StoreOf holds state, view reads with dot syntax,
// store.send(.action) drives every change.

الأسئلة الشائعة

هل درس «المخزن وتكامل SwiftUI» مجاني؟

نعم — نص درس «المخزن وتكامل SwiftUI» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.

ماذا ستتعلم في «المخزن وتكامل SwiftUI»؟

حرّك العروض انطلاقًا من مخزن TCA. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «المخزن وتكامل SwiftUI»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الحالة والإجراء والمختزل
  2. المخزن وتكامل SwiftUI
  3. التأثيرات والتبعيات
  4. تركيب الميزات واختبارها
← العودة إلى Swift Academy