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

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

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

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

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

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

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

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

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

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

بعد ذلك، اتّبِع الخطوات التالية:

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

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

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

  5. اضبط محاكي SQL Connect واستخدِمه و كرِّر العملية.

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

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

firebase init dataconnect:sdk

تعديل حِزم تطوير البرامج (SDK) أثناء إنشاء النماذج الأولية

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

إذا كنت لا تستخدم إضافة SQL Connect لبرنامج VS Code، يمكنك استخدام واجهة سطر الأوامر في Firebase للحفاظ على حِزم تطوير البرامج (SDK) التي تم إنشاؤها حديثة.

firebase dataconnect:sdk:generate --watch

إنشاء حِزم تطوير البرامج (SDK) في مسارات الإصدار

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

firebase dataconnect:sdk:generate

بدء حزمة تطوير البرامج (SDK) لنظام التشغيل iOS في SQL Connect

ابدأ مثيل SQL Connect باستخدام المعلومات التي استخدمتها لإعداد SQL Connect. يمكنك العثور على هذه المعلومات في قواعد البيانات ومساحة التخزين > SQL Connect صفحة في وحدة تحكُّم Firebase.

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

سينشئ محاكي SQL 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)")

لاسترداد فيلم، ستستخدم مرجع طلب بحث. جميع مراجع طلبات البحث هي ناشرو Observable. استنادًا إلى الناشر الذي تم ضبطه (راجِع 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")

الاشتراك في التغييرات

راجِع مقالة الحصول على آخر المعلومات من SQL Connect في الوقت الفعلي.

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

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

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

في سير عمل SQL 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
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    يمكنك استخدام محاكي SQL Connect، سواء من إضافة SQL 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) في SQL Connect

    يمثّل خادم SQL Connect أنواع بيانات GraphQL الشائعة والمخصّصة. ويتم تمثيلها في حزمة تطوير البرامج (SDK) على النحو التالي.

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