استخدام حِزم تطوير البرامج (SDK) لنظام التشغيل iOS التي تم إنشاؤها

تتيح لك حِزم تطوير البرامج (SDK) من جهة العميل Firebase Data Connect إرسال طلبات البحث والتعديلات من جهة الخادم مباشرةً من تطبيق Firebase. ويمكنك إنشاء حزمة تطوير برامج (SDK) مخصّصة من جهة العميل بالتزامن مع تصميم المخططات وطلبات البحث والتعديلات التي تنشرها في خدمة Data Connect. بعد ذلك، يمكنك دمج طرق من حزمة تطوير البرامج هذه في منطق برنامجك.

كما ذكرنا في موضع آخر، من المهم الإشارة إلى أنّ Data Connect طلبات البحث وعمليات التعديل لا يتم إرسالها من خلال رمز العميل وتنفيذها على الخادم. في المقابل، عند نشر عمليات Data Connect، يتم تخزينها على الخادم مثل "وظائف السحابة الإلكترونية". وهذا يعني أنّه عليك نشر تغييرات مقابلة من جهة العميل لتجنُّب تعطيل التطبيق للمستخدمين الحاليين (على سبيل المثال، في إصدارات التطبيق القديمة).

لهذا السبب، يوفّر لك Data Connect بيئة تطوير وأدوات تتيح لك إنشاء نماذج أولية للمخططات والطلبات وعمليات التعديل التي يتم نشرها على الخادم. تنشئ أيضًا حِزم SDK من جهة العميل تلقائيًا أثناء إنشاء النماذج الأولية.

بعد تكرار التحديثات على خدمتك وتطبيقات العميل، يصبح كلا التحديثَين على جهة الخادم ومن جهة العميل جاهزًا للنشر.

ما هي خطوات سير عمل تطوير العملاء؟

إذا اتّبعت الخطوات الواردة في البدء، تكون قد تعرّفت على سير عملية التطوير بشكل عام في Data Connect. في هذا الدليل، ستجد معلومات أكثر تفصيلاً حول إنشاء حِزم تطوير برامج (SDK) بلغة Swift من المخطط الخاص بك والتعامل مع طلبات البحث وعمليات التعديل من جهة العميل.

باختصار، لاستخدام حِزم تطوير البرامج (SDK) التي تم إنشاؤها بلغة Swift في تطبيقات العميل، عليك اتّباع خطوات المتطلبات الأساسية التالية:

  1. أضِف Firebase إلى تطبيق iOS.
  2. لاستخدام حزمة تطوير البرامج (SDK) التي تم إنشاؤها، عليك ضبطها كعنصر تابع في Xcode.

    في شريط التنقّل العلوي في Xcode، اختَر ملف (File) > إضافة موارد الاعتمادية للحزمة (Add Package Dependencies) > إضافة محلية (Add Local)، ثم اختَر المجلد الذي يحتوي على حزمة Package.swift التي تم إنشاؤها.

بعد ذلك:

  1. طوِّر مخطّط تطبيقك.
  2. إعداد إنشاء حزمة تطوير البرامج (SDK):

    • باستخدام الزر إضافة حزمة تطوير البرامج (SDK) إلى التطبيق في إضافة Data Connect VS Code
    • من خلال تعديل connector.yaml
  3. تهيئة رمز العميل واستيراد المكتبات

  4. تنفيذ طلبات البحث وعمليات التعديل

  5. إعداد Data Connect المحاكي واستخدامه والتكرار

إنشاء حزمة تطوير البرامج (SDK) بلغة Swift

استخدِم واجهة سطر الأوامر Firebase لإعداد حِزم تطوير البرامج (SDK) التي تم إنشاؤها باستخدام Data Connect في تطبيقاتك. يجب أن يرصد الأمر init جميع التطبيقات في المجلد الحالي وأن يثبّت حِزم SDK التي تم إنشاؤها تلقائيًا.

firebase init dataconnect:sdk

تحديث حِزم SDK أثناء إنشاء النماذج الأولية

إذا كانت إضافة Data Connect VS Code مثبَّتة، ستحرص دائمًا على أن تكون حِزم SDK التي تم إنشاؤها حديثة.

إذا كنت لا تستخدم إضافة Data Connect في VS Code، يمكنك استخدام Firebase CLI لإبقاء حِزم SDK التي تم إنشاؤها محدّثة.

firebase dataconnect:sdk:generate --watch

إنشاء حِزم SDK في مسارات الإنشاء

يمكنك استخدام Firebase CLI لإنشاء حِزم تطوير البرامج (SDK) الخاصة بـ Data Connect في عمليات إنشاء CI/CD.

firebase dataconnect:sdk:generate

إعداد حزمة تطوير البرامج Data Connect لنظام التشغيل iOS

ابدأ مثيل Data Connect باستخدام المعلومات التي استخدمتها لإعداد Data Connect (تتوفّر جميعها في علامة التبويب Data Connect في وحدة تحكّم Firebase).

الحصول على مثيل موصّل

سيتم إنشاء رمز الموصل بواسطة محاكي Data Connect. إذا كان اسم الموصّل هو movies والحزمة هي movies، كما هو محدّد في connector.yaml، يمكنك استرداد عنصر الموصّل من خلال استدعاء:

let connector = DataConnect.moviesConnector

تنفيذ طلبات البحث وعمليات التعديل

باستخدام عنصر الموصل، يمكنك تنفيذ طلبات البحث وعمليات التعديل كما هو محدّد في رمز مصدر GraphQL. لنفترض أنّ الموصل يتضمّن العمليات المحدّدة التالية:

mutation createMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
  movie_insert(data: {
    title: $title
    releaseYear: $releaseYear
    genre: $genre
    rating: $rating
  })
}

query getMovieByKey($key: Movie_Key!) {
  movie(key: $key) { id title }
}

query listMoviesByGenre($genre: String!) {
  movies(where: {genre: {eq: $genre}}) {
    id
    title
  }
}

يمكنك بعد ذلك إنشاء فيلم باتّباع الخطوات التالية:

let mutationResult = try await connector.createMovieMutation.execute(
  title: "Empire Strikes Back",
  releaseYear: 1980,
  genre: "Sci-Fi",
  rating: 5)

print("Movie ID: \(mutationResult.data.movie_insert.id)")

لاسترداد فيلم، عليك استخدام مرجع طلب بحث. جميع مراجع طلبات البحث هي ناشرون قابلون للمراقبة. استنادًا إلى الناشر الذي تم ضبطه (راجِع connector.yaml))، يتيح الناشر إما استخدام وحدة الماكرو @Observable (الإصدار 17 من نظام التشغيل iOS أو الإصدارات الأحدث) أو تنفيذ بروتوكول ObservableObject. القيمة التلقائية، في حال عدم تحديد أي قيمة، هي الماكرو @Observable المتوافق مع الإصدار 17 من نظام التشغيل iOS والإصدارات الأحدث.

في عرض SwiftUI، يمكنك ربط نتائج طلب البحث باستخدام المتغيّر data المنشور الخاص بمرجع طلب البحث واستدعاء طريقة execute() الخاصة بطلب البحث لتعديل البيانات. سيتطابق المتغيّر data مع شكل البيانات الذي تم تحديده في تعريف طلب بحث GQL.

تتوافق جميع النتائج التي تم استرجاعها مع بروتوكول Decodable. إذا تضمّنت المفتاح الأساسي للعنصر في عملية استرجاع GQL، ستكون العناصر أيضًا Identifiable، ما يتيح لك استخدامها في المكرّرات.

struct ListMovieView: View {
    @StateObject private var queryRef = connector.listMoviesByGenreQuery.ref(genre: "Sci-Fi")
    var body: some View {
        VStack {
            Button {
                Task {
                    do {
                        try await refresh()
                    } catch {
                        print("Failed to refresh: \(error)")
                    }
                }
            } label: {
                Text("Refresh")
            }
                // use the query results in a view
            ForEach(queryRef.data?.movies ?? [], id: \.self.id) { movie in
                    Text(movie.title)
                }
            }
    }
    @MainActor
    func refresh() async throws {
        _ = try await queryRef.execute()
    }
}

تتيح طلبات البحث أيضًا التنفيذ لمرة واحدة.

let resultData = try await DataConnect.moviesConnector.listMoviesByGenreQuery.execute(genre: "Sci-Fi")

التعامل مع التغييرات في حقول التعداد

يمكن أن يحتوي مخطط التطبيق على تعدادات، ويمكن الوصول إليها من خلال طلبات بحث GraphQL.

عندما يتغيّر تصميم التطبيق، يمكنك إضافة قيم جديدة متوافقة مع التعداد. على سبيل المثال، لنفترض أنّك قرّرت في وقت لاحق من مراحل نشاط تطبيقك إضافة القيمة FULLSCREEN إلى تعداد AspectRatio.

في سير عمل Data Connect، يمكنك استخدام أدوات التطوير المحلية لتعديل الاستعلامات وحِزم SDK.

ومع ذلك، قبل طرح إصدار محدَّث من برامجك، قد تتعطّل البرامج القديمة التي تم نشرها.

مثال على عملية تنفيذ مرنة

تفرض حزمة SDK التي تم إنشاؤها التعامل مع القيم غير المعروفة لأنّ التعدادات التي تم إنشاؤها تحتوي على قيمة _UNKNOWN، ويفرض Swift عبارات switch شاملة.

do {
    let result = try await DataConnect.moviesConnector.listMovies.execute()
    if let data = result.data {
        for movie in data.movies {
            switch movie.aspectratio {
                case .ACADEMY: print("academy")
                case .WIDESCREEN: print("widescreen")
                case .ANAMORPHIC: print("anamorphic")
                case ._UNKNOWN(let unknownAspect): print(unknownAspect)
            }
        }
    }
} catch {
    // handle error
}

تفعيل التخزين المؤقت من جهة العميل

يتضمّن Data Connect ميزة اختيارية للتخزين المؤقت من جهة العميل، ويمكنك تفعيلها من خلال تعديل ملف connector.yaml. عند تفعيل هذه الميزة، ستخزّن حِزم تطوير البرامج (SDK) للعميل التي تم إنشاؤها ردود طلبات البحث مؤقتًا على الجهاز، ما قد يقلّل عدد طلبات قاعدة البيانات التي يرسلها تطبيقك ويتيح تشغيل الأجزاء التي تعتمد على قاعدة البيانات في تطبيقك عند انقطاع الاتصال بالشبكة.

لتفعيل التخزين المؤقت من جهة العميل، أضِف إعدادات التخزين المؤقت من جهة العميل إلى إعدادات الموصل:

generate:
  swiftSdk:
    outputDir: "../ios"
    package: "FirebaseDataConnectGenerated"
    clientCache:
      maxAge: 5s
      storage: persistent

يتضمّن هذا الإعداد مَعلمتَين، وكلاهما اختياري:

  • maxAge: الحد الأقصى لعمر الرد المخزّن مؤقتًا قبل أن تجلب حزمة SDK للعميل قيمًا جديدة. أمثلة: "0" أو "30 ثانية" أو "ساعة و30 دقيقة".

    القيمة التلقائية لـ maxAge هي 0، ما يعني أنّه يتم تخزين الردود مؤقتًا، ولكن ستجلب حزمة تطوير البرامج (SDK) للعميل دائمًا قيمًا جديدة. لن يتم استخدام القيم المخزّنة مؤقتًا إلا عندما يتم ضبط CACHE_ONLY على execute().

  • storage: يمكن ضبط حزمة SDK الخاصة بالعميل لتخزين الردود مؤقتًا إما في مساحة التخزين persistent أو في memory. ستبقى النتائج المخزّنة مؤقتًا في مساحة تخزين persistent متاحة عند إعادة تشغيل التطبيق. في حِزم تطوير البرامج لنظام التشغيل iOS، تكون القيمة التلقائية هي persistent.

بعد تعديل إعدادات التخزين المؤقت للموصل، أعِد إنشاء حِزم تطوير البرامج (SDK) الخاصة بالعميل وأعِد إنشاء تطبيقك. بعد الانتهاء من ذلك، ستخزّن execute() الردود مؤقتًا وستستخدم القيم المخزّنة مؤقتًا وفقًا للسياسة التي أعددتها. يحدث ذلك تلقائيًا بشكل عام، بدون أي خطوات إضافية من جانبك، ولكن يُرجى ملاحظة ما يلي:

  • يكون السلوك التلقائي لـ execute() كما هو موضّح أعلاه: إذا تم تخزين نتيجة طلب البحث مؤقتًا وكانت القيمة المخزَّنة مؤقتًا ليست أقدم من maxAge، يتم استخدام القيمة المخزَّنة مؤقتًا. يُطلق على هذا السلوك التلقائي اسم سياسة PREFER_CACHE.

    يمكنك أيضًا تحديد ما إذا كان سيتم عرض القيم المخزّنة مؤقتًا فقط (CACHE_ONLY) أو جلب قيم جديدة من الخادم بدون شروط (SERVER_ONLY) عند استدعاء execute() بشكل فردي.

    try await execute(fetchPolicy: .cacheOnly)
    
    try await execute(fetchPolicy: .serverOnly)
    

    إنشاء نموذج أولي لتطبيق iOS واختباره

    تجهيز العملاء لاستخدام محاكي محلي

    يمكنك استخدام محاكي Data Connect، سواء من إضافة Data Connect VS Code أو من واجهة سطر الأوامر.

    تكون عملية إعداد التطبيق للاتصال بالمحاكي هي نفسها في كلتا الحالتين.

    let connector = DataConnect.moviesConnector
    // Connect to the emulator on "127.0.0.1:9399"
    connector.useEmulator()
    
    // (alternatively) if you're running your emulator on non-default port:
    connector.useEmulator(port: 9999)
    
    // Make calls from your app
    

    أنواع البيانات في حِزم تطوير البرامج (SDK) التي تحمل الرقم Data Connect

    يمثّل خادم Data Connect أنواع بيانات GraphQL الشائعة والمخصّصة. يتم تمثيل هذه القيم في حزمة SDK على النحو التالي.

    Data Connect النوع Swift
    سلسلة سلسلة
    Int Int
    عائم مزدوج
    قيمة منطقية Bool
    معرِّف فريد عالمي (UUID) معرِّف فريد عالمي (UUID)
    التاريخ FirebaseDataConnect.LocalDate
    الطابع الزمني FirebaseCore.Timestamp
    Int64 Int64
    أي FirebaseDataConnect.AnyValue