نسخة مستنسخة من Instagram باستخدام SwiftUI و GraphQL

سنبدأ اليوم سلسلة من التدوينات التي ستعلمك كيفية استخدام الكثير من الأدوات الرائعة لبناء شبكتك الاجتماعية الخاصة بك: تطبيق يشبه تطبيق Instagram.

لن نقتصد في التكنولوجيا وسوف نستخدم الأحدث والأفضل: Parse، و GraphQL، وبعض NodeJS، وخاصةً إطار عمل SwiftUI الأحدث (الذي لم يصدر بعد) من Apple SwiftUI.

سيستغرق هذا الأمر بضع منشورات لكي يعمل بكامل طاقته، ولكن عندما نصل إلى هناك، ستدرك مدى سهولة تشغيل أفكارك بأقل جهد ممكن هنا في Back4app.

للتعلم بشكل أفضل، قم بتنزيل مشروع استنساخ iOS Instagram Clone مع التعليمات البرمجية المصدرية.

لذا، يبدو أن الوقت قد حان لـ …

هل تريد بداية سريعة؟

استنسخ هذا التطبيق من مركزنا وابدأ باستخدامه دون أي متاعب!

بعض المقدمات

حسنًا، ربما تعرف بالفعل الفوائد الهائلة التي يجلبها Parse لعملية التطوير الخاصة بك، خاصةً إذا تمت استضافتها في Back4app، حيث تزيد مجموعة أدواتنا من الإنتاجية بمقادير هائلة.

وقد أظهرت لك آخر منشوراتنا حول GraphQL مدى سهولة الحفاظ على تطوير واجهات برمجة التطبيقات بمرور الوقت إذا كنت تستخدمها. إذا فاتتك تلك المنشورات، أقترح عليك بشدة أن تأخذ وقتك وتقرأها، لأنها ستحسن فهمك بشكل كبير أثناء تقدمنا.
يمكنك قراءة المزيد حول GraphQL ولدينا أيضًا منشور كامل حول كيفية الاستخدام في مقالة واجهة برمجة تطبيقات الويب.
يمكنك أيضًا الاطلاع على بعض التكامل مع NodeJS في وظائف الرمز السحابي قراءة GraphQL و NodeJS.

هذا يتركنا مع SwiftUI.
SwiftUI، وفقًا لشركة Apple، “طريقة مبتكرة وبسيطة بشكل استثنائي لبناء واجهات مستخدم عبر جميع منصات Apple مع قوة Swift”.

أنا نفسي أحب أن أعتقد أن SwiftUI أكثر من ذلك.

إذا كنت مثلي تعمل على تطوير البرمجيات لبعض الوقت، فربما تعرف أن مجتمع المطورين لطالما انقسم بين سهولة استخدام Storyboards، أو واجهة بناء واجهة المستخدم بالسحب والإفلات من Apple، أو قوة واجهة المستخدم البرمجية.

تأتي SwiftUI لتجمع بين أفضل ما في العالمين: فهي سهلة بما يكفي للمبتدئين لتعلمها، بينما تحافظ على قابلية الصيانة لواجهة المستخدم المشفرة.
ادمج ذلك مع العرض في الوقت الفعلي، بحيث يمكن للمطورين رؤية المخرجات المرئية لما يقومون بترميزه بسهولة، واجعلها ذات اتجاهين بحيث إذا قمت بتغيير الشيفرة، سينعكس ذلك على واجهة المستخدم، وإذا قمت بتغيير واجهة المستخدم بيانياً سينعكس ذلك على الشيفرة، وما تحصل عليه هو واحدة من أقوى الطرق وأكثرها سهولة لتقديم واجهات مستخدم مصممة بشكل جميل وقابلة للصيانة بمرور الوقت.

إذًا، ما الذي ستحتاجه؟

في وقت كتابة هذا المقال، كانت Apple لا تزال تختبر الإصدار التجريبي من macOS Catalina الجديد، و XCode 11، و iOS 13 وبعض المنتجات الأخرى التي ستصل إلى الرفوف قريباً.

في حين يمكنك استخدام XCode 11 مع macOS Mojave، ستحتاج إلى Catalina لعرض معاينات SwiftUI في الوقت الحقيقي.

screen-shot-2019-08-26-at-09-07-25

لا Catalina ؟ لا معاينات لك!

هذا قرار يجب عليك اتخاذه لأنني وجدت أن تغيير التغيير من Bash إلى ZSH كصدفة macOS الرسمية في Catalina قد عطل العديد من أدواتي ونصوصي التي أستخدمها في سير عملي اليومي، قررت البقاء في Mojave لفترة من الوقت. الأمر متروك لك لتقرر ما إذا كنت ستحدث أم لا.

أيضًا، ستحتاج إلى حساب Back4app مع إنشاء تطبيق. يمكنك معرفة كيفية إنشاء تطبيقك الأول في وثائق Back4app.

أخيرًا وليس آخرًا، سنستخدم تطبيق Apollo Client من أجل دمج GraphQL في مشروعنا. إذا لم تكن لديك خبرة في ذلك، فقد كتبت منشورًا مفصلاً للغاية حول كيفية تكوينه واستخدامه مصادقة الويب.

لذا، قبل أن نبدأ، ستحتاج إلى

  • XCode 11 مثبتًا (مع macOS Catalina إذا كنت تريد رؤية المعاينات)
  • تطبيقك الجديد الذي تم إنشاؤه في Back4app
  • تثبيت عميل Apollo وتهيئته

سيُطلق على تطبيقي اسم Back4Gram، حيث سيشبه تطبيق Instagram.

صفنا الأول

دائمًا ما أخبركم يا رفاق عن كيفية إنشاء Parse لفئة المستخدم، حتى تتمكن من تسجيل مستخدمين جدد ومصادقة المستخدمين الحاليين، وفئة الدور، حتى تتمكن من تجميع المستخدمين الذين لديهم امتيازات مماثلة. هذا أمر رائع لأنه، على الأقل للمصادقة، لا يتعين علينا إنشاء أي فئة.

تحتوي فئة المستخدم على ثلاث خصائص يتم إنشاؤها تلقائيًا، اثنتان منها إلزاميتان وواحدة اختيارية:

  • اسم المستخدم (إلزامي)
  • كلمة المرور (إلزامية)
  • البريد الإلكتروني (اختياري)

هذه كافية لتطبيقنا لتسجيل المستخدمين وإدارتهم.

كما تعلم على الأرجح أن سياسة Apple بشأن تخزين رسائل البريد الإلكتروني للمستخدمين صارمة للغاية، لذا أوصي بعدم طلب هذه المعلومات أو الاحتفاظ بها وإلا قد لا تتم الموافقة عليها.

بما أن هذا هو برنامج تعليمي فقط، سأطلب من المستخدم إدخال تلك المعلومات، فقط حتى تتمكن من رؤية كيفية عملها.

screen-shot-2019-08-26-at-09-30-18

فئات المستخدم والدور التي تم إنشاؤها تلقائيًا

كما لو أن ذلك لم يكن مفيدًا بما فيه الكفاية، فإن تطبيقك الذي تم إنشاؤه حديثًا يحتوي بالفعل على استعلامات GraphQL و Mutations التي تم إنشاؤها تلقائيًا لنا. هذا صحيح بالنسبة لفئاتنا التي تم إنشاؤها تلقائيًا وأيضًا لأي فئة أخرى تقوم بإنشائها بمرور الوقت. لقد قمنا بتغطيتك بالوثائق أيضًا!

screen-shot-2019-08-26-at-09-39-46

هل أخبرتك أن لدينا أيضًا الإكمال التلقائي؟ نعم لدينا!

إذًا، ستكون الطفرة الأولى كما هو مذكور أعلاه، وسنستخدم طفرتنا الخاصة بـ SignUp() لإنشاء مستخدم جديد:

سيعتمد الاستعلام على إصدار Parse الذي تستخدمه:

Parse 3.7.2:

طفرة SignUpUser($ اسم المستخدم: سلسلة!, $ كلمة المرور: سلسلة!, $ كلمة المرور: سلسلة!, $ البريد الإلكتروني: سلسلة) {
  المستخدمون {
    تسجيل الدخول(
      الحقول: { اسم المستخدم: $ اسم المستخدم، كلمة المرور: $ كلمة المرور، البريد الإلكتروني: $ البريد الإلكتروني: $ البريد الإلكتروني }
    ) {
      معرف الكائن
    }
  }
}

Parse 3.8:

طفرة تسجيل الدخول($ اسم المستخدم: سلسلة!, $ كلمة المرور: سلسلة!, $ كلمة المرور: سلسلة!, البريد الإلكتروني: سلسلة) {
    تسجيل الدخول(
      الحقول: { اسم المستخدم: $ اسم المستخدم، كلمة المرور: $ كلمة المرور، البريد الإلكتروني: $ البريد الإلكتروني: $ البريد الإلكتروني }
    ) {
      معرف الكائن
    }
}

Parse 3.9:

طفرة تسجيل الدخول($ اسم المستخدم: سلسلة!, $ كلمة المرور: سلسلة!, $ كلمة المرور: سلسلة!, البريد الإلكتروني: سلسلة) {
    تسجيل الدخول(
      الحقول: { اسم المستخدم: $ اسم المستخدم، كلمة المرور: $ كلمة المرور، البريد الإلكتروني: $ البريد الإلكتروني: $ البريد الإلكتروني }
    ) {
      معرف
    }
}

لاحظ أنني أجعل المتغيرين اسم المستخدم وكلمة المرور إلزاميين من خلال وجود “!” في نهاية نوعيهما، بينما البريد الإلكتروني اختياري، من خلال عدم وجود “!” بعد نوعه.

في النهاية، أقوم بإرجاع معرف الكائن للمستخدم الذي تم إنشاؤه حديثًا.

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

Parse 3.7.2

الطفرة logInUser($ اسم المستخدم: سلسلة!, $ كلمة المرور: سلسلة!) {
  المستخدمين{
    تسجيل الدخول(اسم المستخدم: $username: $username، كلمة المرور: $password){ {
      رمز الجلسة
    }
  }
}

Parse 3.8

طفرة logInUser($ اسم المستخدم: سلسلة!, $ كلمة المرور: سلسلة!) { {
    تسجيل الدخول(اسم المستخدم: $ اسم المستخدم، كلمة المرور: $ كلمة المرور){ {
      رمز الجلسة
    }
}

Parse 3.9

طفرة logInUser($ اسم المستخدم: سلسلة!, $ كلمة المرور: سلسلة!){ {
    تسجيل الدخول(اسم المستخدم: $ اسم المستخدم، كلمة المرور: $ كلمة المرور){ {
      رمز الجلسة
    }
}

أخيرًا وليس آخرًا، طفرة للمستخدم لتسجيل الخروج، والتي لا تتطلب أي معلمة وتعيد فقط قيمة Boolean:

Parse 3.7.2

طفرة تسجيل خروج المستخدم{
  المستخدمين{
    تسجيل الخروج
  }
}

Parse 3.8

طفرة logOutUser{
    تسجيل الخروج
}

Parse 3.9

طفرة logOutUser{
    تسجيل الخروج
}

أضف كل تلك الملفات إلى ملف جديد يسمى UserMutations.graphql، واحفظ أيضًا ملف schema.graphql الذي تعلمت كيفية تنزيله في مقالنا السابق.

احتفظ بهذه الملفات في مكان آمن لأننا سنضيفها إلى…

مشروع SwiftUI

لنقم بإنشاء مشروع SwiftUI الخاص بنا.

قم بتشغيل XCode 11 واضغط على “إنشاء مشروع XCode جديد” من نافذة مرحبًا بك في XCode.
إذا لم تظهر لك هذه النافذة، يمكنك دائمًا الانتقال إلى ملف > جديد > مشروع.

اختر تطبيق iOS في الأعلى، ثم تطبيق عرض واحد. أعطه اسمًا جيدًا وتذكر أن تختار Swift كلغة و SwiftUI كواجهة مستخدم:

screen-shot-2019-08-26-at-10-15-21

لا تنس أن تختار SwiftUI كواجهة المستخدم

والآن، قم بتثبيت عميل Apollo Client كما تعلمت في مقالة واجهة برمجة تطبيقات الويب الخاصة بنا، وبعد ذلك، أضف ملفي UserMutations.graphql و schema.graphql إلى مشروعك.
قم بتجميع وإضافة ملف API.swift الذي تم إنشاؤه حديثًا إلى المشروع.

في هذه المرحلة ما أتوقع أن يكون لديك هو

  • تثبيت XCode 11 وتشغيله
  • عميل Apollo مثبت ومدمج في مشروع XCode الخاص بك
  • إضافة ملفي UserMutations.graphql و schema.graphql إلى مشروع XCode الخاص بك
  • تمت إضافة ملف API.swift المُنشأ إلى مشروع XCode الخاص بك

يجب أن يبدو مشروعك مشابهًا لهذا:

screen-shot-2019-08-26-at-10-32-00

كل شيء مدمج في XCode 11

نحن الآن جاهزون لبدء تشغيل SwiftUI.

قم بالتسجيل الآن في Back4App وابدأ في إنشاء تطبيق Instagram Clone App الخاص بك.

تحديد ضوابطنا

قبل أن نتمكن من تسجيل دخول أو خروج مستخدم، يجب أن يكون لدينا هذا المستخدم الذي تم إنشاؤه في المقام الأول. لذلك سنقوم بترميز شاشة تسجيل الدخول أولاً.

عادة، يمكن أن يكون لدينا 4 إلى 5 عناصر تحكم في تلك الشاشة:

  • نوع من النص لإخبار المستخدم ما هي الشاشة (نص)
  • اسم المستخدم (عنصر تحكم إدخال نص)
  • كلمة المرور (عنصر تحكم إدخال نصي آمن)
  • تأكيد كلمة المرور (اختياري، يعتمد على النظام الأساسي، عنصر تحكم إدخال نص آمن)
  • البريد الإلكتروني (عنصر تحكم إدخال نص منسق)
  • زر التسجيل (زر)

نظرًا لأن هذا سيكون تطبيقًا للهاتف المحمول، قررت عدم وضع عنصر تحكم إدخال نص تأكيد كلمة المرور، لأن معظم منصات الهاتف المحمول تسمح للمستخدم برؤية آخر حرف تمت كتابته وفي معظم الحالات يكون ذلك كافيًا للمستخدم لتحديد ما إذا كانت كلمة المرور مكتوبة بشكل صحيح.

ستظهر عناصر التحكم هذه محاذية عموديًا، واحدة أسفل الأخرى، بالترتيب أعلاه، ولكل منها لونها الخاص.

بناء واجهة المستخدم فعليًا

كما ذكرت سابقًا، أنا لا أستخدم نظام macOS Catalina لذا لن أقوم بتمكين المعاينات، لكنني سأقوم بتجميع النتائج وأعرضها لكم مع الشيفرة كما كانت لدي.

قم بإنشاء طريقة عرض SwiftUI جديدة من خلال الانتقال إلى ملف > جديد > ملف ثم اختيار طريقة عرض SwiftUI في قسم واجهة المستخدم.

screen-shot-2019-08-26-at-11-08-58

قم بتسمية هذا الملف SignUpView.swift وسيظهر مدمجًا في مشروعك.

screen-shot-2019-08-26-at-11-14-13

ستلاحظ أن طريقة العرض التي تم إنشاؤها حديثًا تحتوي بالفعل على عنصر تحكم نصي يحتوي على سلسلة “Hello World!”.

screen-shot-2019-08-26-at-11-18-31

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

لقد قررنا أن نجعل عناصر التحكم الخاصة بنا محاذاة عموديًا ولدى SwiftUI عنصر تحكم خاص بذلك اسمه VStack (المكدس العمودي): كل شيء موجود داخل VStack سيتم تكديسه عموديًا تلقائيًا، لذا، فقط للاختبار، دعنا نضيف عنصر تحكم VStack إلى ContentView.swift الخاص بنا وداخله، أضف مرتين SignUpView:

screen-shot-2019-08-26-at-11-39-39

نضيف SignUpView مرتين في VStack: يظهر مرتين بمحاذاة عموديًا

الآن، كم هذا رائع! إذا احتجنا إلى المزيد من عناصر التحكم، يمكننا الاستمرار في إضافتها!

دعونا نزيل VStack والازدواجية ونحصل على SignUpView() واحد فقط في طريقة العرض هذه ثم نعود إلى SignUpView ونبدأ بتغييره، كما رأينا بالفعل نتائج اختبارنا. يجب أن تبدو طريقة عرض المحتوى الخاصة بك مشابهة لهذا الآن:

هيكلة ContentView: طريقة عرض {
    متغير الجسم: طريقة عرض ما {
        SignUpView()
    }
}

نحن نعلم بالفعل أننا سنحتاج إلى VStack مع النص في أعلى الشاشة، لذا دعنا نضيف VStack إلى SignUpView بدلاً من ذلك ونغير سلسلة “Hello World!” إلى شيء مفيد، مثل “تسجيل”. يجب أن تبدو SignUpView الخاصة بنا هكذا:

هيكلة SignUpView: طريقة عرض {
    متغير الجسم: طريقة عرض ما {
        VStack{
            نص("تسجيل")
        }
    }
}

وبما أننا نعرف بالفعل عناصر التحكم التي يجب أن نضيفها أسفل ذلك، يمكننا إضافة

  • حقل نصي لاسم المستخدم
  • حقل آمن لكلمة المرور
  • حقل نص للبريد الإلكتروني
  • زر للتسجيل

يتشابه كل من TextFields و SecureField مع UITextField القديم، ولكن يجب أن يعتمد على الربط بالحالة، لذا سنقوم بتعريفهما على أنهما

عنصر تحكم(“عنصر نائب”، النص: stateValueToBindTo)

والخطوة الأولى هي إعلان تلك الحالة للربط بها:

@State var اسم المستخدم: سلسلة = ""
@State var كلمة المرور: سلسلة = ""
@الدولة متغير البريد الإلكتروني: سلسلة = ""

بعد الانتهاء من ذلك، يمكننا البدء بإضافة عناصر التحكم الخاصة بنا:

نص("تسجيل")
حقل النص("اسم المستخدم"، النص: $username)
حقل آمن("كلمة المرور"، النص: $ كلمة المرور)
TextField("البريد الإلكتروني (اختياري)"، النص: $ البريد الإلكتروني)

أخيرًا وليس آخرًا، يمكننا إضافة الزر الذي يحتوي على هذه البنية

زر(الإجراء: {
/ / رمز للتشغيل عند تشغيله
}){
//المحتوى
}

كما لاحظت على الأرجح، يعمل هذا الزر تمامًا مثل زر UIButton، ولكن بنيته أكثر مرونة حيث يمكننا تحديد محتواه برمجيًا، وإضافة أي شيء فيه عمليًا: نص، صورة. سمِّ ما شئت.

لقد اختفت بنية الهدف/الإجراء القديمة، واستُبدلت ببنية جديدة: {} للتعامل مع السلوك عند النقر عليه.

سيحتوي الزر الخاص بنا على نص فيه يقول “اشترك!”، لذا دعنا نضيفه:

زر(إجراء: {

}){
    نص("اشترك!")
}

ويجب أن تبدو شفرتك النهائية هكذا

هيكلة SignUpView: عرض {
    @حالة متغير اسم المستخدم: سلسلة = ""
    @حالة متغير كلمة المرور: سلسلة = ""
    @الدولة متغير البريد الإلكتروني: سلسلة = ""
    
    متغير الجسم: عرض ما {
        VStack{
            نص("تسجيل")
            حقل النص("اسم المستخدم"، النص: $username)
            حقل آمن("كلمة المرور"، النص: $ كلمة المرور)
            حقل نصي("البريد الإلكتروني (اختياري)"، النص: $البريد الإلكتروني)
            زر(إجراء: {
                
            }){
                نص("تسجيل!")
            }
        }
    }
}

وماذا عن المعاينة؟

screen-shot-2019-08-26-at-16-11-48

تبدو واعدة، ولكن يمكننا تحسينها كثيرًا من خلال تعيين بعض الخصائص المرئية.
وإذا كان هناك شيء رائع جدًا في SwiftUI هو أنه يمكنك إضافة خصائص مرئية إلى الشيفرة ورؤية التغييرات في الوقت الفعلي أيضًا!
لنجرب بعضها!

أولًا، دعنا نعلن عن الألوان التي سنستخدمها

لنجعل لون LightGreyColor = لون (أحمر: 239.0/255.0، أخضر: 243.0/255.0، أزرق: 244.0/255.0، عتامة: 1.0)
    دعونا LightBlueColor = اللون(أحمر: 36.0/255.0، أخضر: 158.0/255.0، أزرق: 235.0/255.0، التعتيم: 1.0)

ثم دعنا نضيف بعض الميزات الرائعة:

بعض الحشو بحيث يكون لدينا بعض المسافة بين تلك العناصر.
اضبط خصائص الخلفية والألوان الأمامية حتى يكون لدينا عناصر تحكم متناسقة مع علامتنا التجارية.
بعض خاصية cornerRadius حتى نحصل على زوايا مستديرة.
وتعيين الخط و fontWeight لجعل الأشياء أجمل.
ها نحن ذا!

screen-shot-2019-08-26-at-16-30-55

هل هذا جميل أم ماذا؟
فقط لتتبع شفرتنا في هذه المرحلة:

هيكلة SignUpView: عرض {
    @State var اسم المستخدم: سلسلة = ""
    @حالة متغير كلمة المرور: سلسلة = ""
    @الدولة متغير البريد الإلكتروني: سلسلة = ""
    
    دعونا lightGreyColor = اللون (أحمر: 239.0/255.0، أخضر: 243.0/255.0، أزرق: 244.0/255.0، التعتيم: 1.0)
    دعونا LightBlueColor = اللون(أحمر: 36.0/255.0، أخضر: 158.0/255.0، أزرق: 235.0/255.0، التعتيم: 1.0)

    
    متغير الجسم: طريقة عرض ما {
        VStack{
            نص("تسجيل")
                .font(.largeTitle)
                .ForegroundColor(lightBlueColor)
                .fontWeight(.semibold)
                .الحشو(.سفلي، 20)
            حقل نصي("اسم المستخدم"، النص: اسم المستخدم $)
                .الحشو()
                .خلفية(لون رمادي فاتح)
                .cornerRadius (5.0)
                .الحشو(.سفلي، 20)
            حقل آمن("كلمة المرور"، النص: $ كلمة المرور)
                .الحشو()
                .خلفية(لون رمادي فاتح)
                .cornerRadius(5.0)
                .padding(.bottom, 20)
            TextField("البريد الإلكتروني (اختياري)"، النص: $ البريد الإلكتروني)
                .الحشو()
                .خلفية(لون رمادي فاتح)
                .cornerRadius(5.0)
                .حشوة(.أسفل، 20)
            زر(إجراء: {
                
            }){
                نص("تسجيل!")
                 .font(.headline)
                 .ForegroundColor(.white)
                 .الحشو()
                 .إطار(العرض: 220، الارتفاع: 60)
                 .الخلفية(lightBlueColor)
                 .cornerRadius(15.0)
            }
        }.padding()
    }
}

إذًا، لدينا شاشتنا اللامعة الجميلة جاهزة تقريبًا.
ماذا عن…

بعض الوظائف

الآن بعد أن جهزنا واجهة المستخدم الخاصة بنا وأنجزناها، حان الوقت لإضافة استدعاءات Apollo إلى طرق GraphQL الخاصة بنا.

نظرًا لأننا سنستخدم هذه الاستدعاءات في جميع طرق العرض تقريبًا، يجب أن ننشئ عميل Apollo في مكان يمكن لجميع طرق العرض الوصول إليه. هذا المكان هو AppDelegate.swift.

أعلن عن عميل Apollo الخاص بك هناك أسفل

استيراد UIKit

وبداية الكتلة البرمجية

@UIA التطبيق الرئيسي
صنف AppDelegate: UIResponder, UIApplicationDelegate {
...

تمامًا كما أوضحنا لك في مقالنا السابق، ومن الآن فصاعدًا يمكن لجميع طرق العرض تنفيذ استعلامات GraphQL والطفرات.
يجب عليك أولاً استيراد إطار عمل Apollo ثم إنشاء عميلك على هذا النحو:

استيراد Apollo

// تهيئة عميل Apollo.
// المزيد عن ذلك هنا: https://www.back4app.com/docs/ios/swift-graphql
دع Apollo: ApolloClient = {
    دع التهيئة = URLSConfiguration.default.com
    configuration.httpAdditionalHeaders = [
        "X-Parse-Application-Id": "YourAppIdIdHere",
        "X-Parse-Client-Key": "YourClientKeyKeyHere"
    ]
    
    دع عنوان url = URL(سلسلة: "https://parseapi.back4app.com/graphql")!
    
    إرجاع ApolloClient(
        networkTransport: HTTPNetworkTransTransport(
            url: url,
            التكوين: التكوين
        )
    )
}()

ما عليك سوى استبدال السلاسل YourAppIdHere و YourClientKeyKeyHere بالقيم الحالية ويمكننا المضي قدمًا.

كما خمنت على الأرجح، يجب أن ننفذ طفرة تسجيل الدخول عند النقر على زر تسجيل الدخول، لذا، في كتلة الإجراء، دعنا نسميها

            // تنفيذ طفرة SignUpUser، مع تمرير المعلمات التي حصلنا عليها للتو من TextFields
            apollo.perform(طفرة: طفرة SignUpUpUserMutation(اسم المستخدم: username: self.username، كلمة المرور: self.password، البريد الإلكتروني: self.email)){ النتيجة في
                // دعنا نبدل النتيجة حتى نتمكن من فصل النتيجة الناجحة عن الخطأ
                تبديل النتيجة {
                    // في حالة النجاح
                    حالة .نجاح(دعنا نبدل النتيجة GraphQLResult):
                        // نحاول Parse النتيجة
                        إذا سمحنا ل objId = graphQLResult.data.data?.users?.signUp.objectId {
                            طباعة ("مستخدم تم إنشاؤه باستخدام ObjectId: " + objId)
                        }
                        // ولكن في حالة وجود أي أخطاء في GraphQL نقدم تلك الرسالة
                        وإلا إذا تركنا الأخطاء = GraphQLResult.errors {
                            // أخطاء GraphQL
                            طباعة (أخطاء)
                            
                        }
                    // في حالة الفشل، نقدم تلك الرسالة
                    حالة .فشل(دع الخطأ):
                      // أخطاء الشبكة أو تنسيق الاستجابة
                      طباعة(خطأ)
                }
            }

سيعمل ذلك ولكن طريقتا print() هاتان ستطبعان إلى وحدة التحكم فقط. نحن بحاجة إلى تقديم تنبيه للمستخدم، لذا دعنا نغيره إلى تنبيه، بالبنية التالية:

تنبيه(العنوان: نص(“العنوان”)، رسالة: نص(“رسالة”)، زر الفصل: .افتراضي (نص(“TextOfButton”)))

نظرًا لأننا سنحتاج إلى تغيير العنوان والرسالة في وقت التشغيل، يجب علينا تعيين بنية للتعامل مع تلك القيم، حيث لا يمكن تغيير المتغيرات الذاتية في وقت التشغيل:

بنية الرسالة {
    var AlertTitle: سلسلة = ""
    var alertText: سلسلة = ""
}

var myMessage = رسالة()

وأنشئ أيضًا حالة حتى يتمكن العرض من معرفة وقت إظهار التنبيه:

@حالة خاصة متغير خاص إظهار التنبيه = خطأ

ويجب أن يكون الرمز الكامل لإجراء الزر الخاص بنا هكذا:

زر(الإجراء: {
            // تنفيذ طفرة SignUpUser، مع تمرير المعلمات التي حصلنا عليها للتو من حقول النص
            apollo.perform(طفرة: تسجيل تسجيل المستخدم (اسم المستخدم: اسم المستخدم الذاتي، كلمة المرور: كلمة المرور الذاتية، البريد الإلكتروني: البريد الإلكتروني الذاتي)){ النتيجة في
                // دعنا نبدل النتيجة حتى نتمكن من فصل النتيجة الناجحة عن الخطأ
                تبديل النتيجة {
                    // في حالة النجاح
                    حالة .نجاح(دعنا نبدل النتيجة GraphQLResult):
                        // نحاول Parse النتيجة
                        في حالة السماح ل objId = graphQLResult.data.data?.users?.signUp.objectId {
                            myMessage.alertTitle = "نعم!"
                            myMessage.alertText = "سجل المستخدم!"
                            
                            self.showAlert = صحيح

                            طباعة ("مستخدم تم إنشاؤه باستخدام ObjectId: " + objId)
                        }
                        // ولكن في حالة وجود أي أخطاء في GraphQL نقدم تلك الرسالة
                        وإلا إذا تركنا الأخطاء = GraphQLResult.errors {
                            // أخطاء GraphQL

                            myMessage.alertTitle = "عفوًا!"
                            myMessage.alertText = "لدينا خطأ GraphQL: " + errors.description.mistakes.mistakes.description
                            ذاتي.showAlert = صحيح

                            طباعة(أخطاء)
                        }
                    // في حالة الفشل، نقدم هذه الرسالة
                    حالة .فشل(دع الخطأ):
                        // أخطاء الشبكة أو أخطاء تنسيق الاستجابة
                        myMessage.alertTitle = "عفوًا!"
                        myMessage.alertText = "لدينا خطأ: " + error.error.localizedDescription
                        ذاتي.showAlert = صحيح
                        
                        طباعة(خطأ)
                }
            }
           }){
               نص("تسجيل!")
                .font(.headline)
                .ForegroundColor(.white)
                .الحشو()
                .إطار(العرض: 220، الارتفاع: 60)
                .الخلفية(lightBlueColor)
                .cornerRadius(15.0)
           }
           .تنبيه(isPresented: $showingAlert) {
                تنبيه(العنوان: نص(myMessage.alertTitle)، رسالة: نص(نص(myMessage.alertText)، زر الفصل: .افتراضي (نص("موافق")))
           }

يبدو واعدًا، أليس كذلك؟

إذًا حان الوقت لـ

قم بالتجميع والتشغيل. حاول تسجيل مستخدم جديد ويجب أن تحصل على…

screen-shot-2019-08-27-at-15-40-59

دعنا نرى ما إذا كان المستخدم قد تم إنشاؤه في لوحة تحكم Parse Dashboard!

screen-shot-2019-08-27-at-15-42-30

خاتمة

لقد أنشأت طريقة عرض SwiftUI تعمل بشكل كامل وتنفذ طفرات GraphQL باستخدام عميل Apollo. كم هذا رائع!

سنواصل العمل على تطبيقنا المستنسخ من Instagram! الخطوات التالية هي تسجيل الدخول والخروج والمنشور في الفرن بالفعل!

ترقبوا!

المرجع

قم بالتسجيل الآن في Back4App وابدأ في إنشاء تطبيق Instagram Clone الخاص بك.


Leave a reply

Your email address will not be published.