iOS: كيفية فتح الروابط العميقة والإخطارات والاختصارات

أداة واحدة للحكم عليهم جميعا

هل سبق لك أن صممت تطبيقًا يتعامل مع ميزة "إعلامات الدفع"؟ إذا كان تطبيقك أكثر تعقيدًا من تطبيق "Hello، World!" ، فمن الأرجح أن الإجابة هي نعم.

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

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

الشيء الجيد هو أنه يمكنك بسهولة العثور على العشرات من المواد التعليمية ، والأمثلة ، والبرامج التعليمية على كل منها إذا كانت هذه المواضيع الثلاثة.

ولكن ما هو التطبيق الخاص بك لدعم كل هذه الميزات؟ هل لديك حقا لتنفيذه كثلاثة مكونات منفصلة؟

قبل المتابعة ، دعونا نوضح المصطلحات:

  1. الروابط العالمية هي وسيلة لاعتراض بعض عناوين URL وبدلاً من معالجة عنوان URL في Safari ، افتح صفحة تطبيق معينة. تتطلب الارتباطات العالمية بعض الأعمال الخلفية ، لذلك سنلتزم بـ Deep Links في هذا البرنامج التعليمي. تعمل الروابط العميقة بالطريقة نفسها ، لكنها تتعامل مع أنظمة عناوين URL المخصصة. لا يختلف تطبيقه كثيرًا ، لذا لن يكون من الصعب إضافة دعم Universal Links إذا كنت بحاجة إليه.
  2. الاختصار هو طريقة التشغيل على الصفحة المحددة بناءً على عنصر الاختصار المحدد عند الضغط على أيقونة التطبيق. تتطلب هذه الميزة الجهاز الذي يعمل باللمس ثلاثي الأبعاد.
  3. الإخطارات: عند النقر فوق الإشعار (إما عن بعد أو محلي) ، سيتم تشغيل التطبيق على صفحة محددة أو القيام بإجراءات معينة.

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

وصفت Apple هذا بـ "خيارات الإطلاق" التي يتم التعامل معها بواسطة AppDelegate didFinishLaunchingWithOptions.

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

للتوضيح ، سأذكرها مرة أخرى: كل هذه الميزات تخدم نفس الغرض - فتح صفحة تطبيق معينة.

والسؤال هو ، كيف نجعل كل شيء يعمل معًا بطريقة لطيفة ونظيفة.

إعداد مشروع

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

  • صفحة رسائلي (المعاينة): يمكن الوصول إليها عبر الاختصار
  • الرسائل (دردشة محددة): يمكن الوصول إليها عبر إشعار الدفع
  • إنشاء قائمة جديدة: يمكن الوصول إليها عبر الاختصار لملف تعريف المضيف فقط
  • نشاطي: يمكن الوصول إليه عبر الاختصار
  • طلب الحجز: يمكن الوصول إليه عبر رابط البريد الإلكتروني (رابط عميق) وإشعار الدفع

أولاً ، قم بإنشاء مشروع بسيط باستخدام ViewController وعنوان التنقل وزر تبديل ملف تعريف s:

إعداد مشروع

عرض تحكم سيكون لها نوع ملف التعريف الحالي وآلية للتبديل بين ملفات التعريف.

لا أستخدم أي أنماط لتصميم البرامج لأن هذا ليس جزءًا من هذا البرنامج التعليمي. في التطبيق الحقيقي ، ستحتاج إلى العثور على بنية أفضل ، من مجرد تخزين ProfileType مباشرة في ViewController.
التعداد ProfileType: String {
   ضيف الحالة = "ضيف" // الافتراضي
   مضيف الحالة = "مضيف"
}
الطبقة ViewController: UIViewController {
   var currentProfile = ProfileType.guest
   تجاوز func viewDidLoad () {
      super.viewDidLoad ()
      configFor (profileType: currentProfile)
   }
   IBAction func didPressSwitchProfile (_ المرسل: أي) {
      currentProfile = currentProfile ==. Guest؟ .المضيف
      configFor (profileType: currentProfile)
   }
   func configFor (profileType: ProfileType) {
      العنوان = profileType.rawValue
   }
}

أداة واحدة للحكم عليهم جميعا

لتصويب الغرض من هذه المقالة ، عندما نفتح صفحة تطبيق معينة ، سأطلق عليها اسم Deep Link ، بغض النظر عن الآلية التي نستخدمها.

الآن ، عندما يكون لدينا بنية أساسية وواجهة مستخدم ، فلننظم قائمة عناصر Deep Link لدينا:

التعداد DeeplinkType {
   تعداد الرسائل
      جذر القضية
      تفاصيل الحالة (المعرف: سلسلة)
   }
   رسائل الحالة (رسائل)
   نشاط القضية
   حالة قائمة جديدة
   طلب حالة (معرف: سلسلة)
}
في هذا البرنامج التعليمي ، لن أغطي نظرية التعداد السريع. يمكنك أن تقرأ هنا ، إذا كنت بحاجة إلى توضيح حول كيفية استخدام التعدادات المتداخلة والتعدادات ذات القيم المرتبطة.

بعد ذلك ، يمكننا إنشاء مدير منفرد ، يحتوي على جميع خيارات الربط العميق:

دع Deeplinker = DeepLinkManager ()
صنف DeepLinkManager {
   fileprivate init () {}
}

إضافة خاصية اختيارية ، والتي ستحتوي على DeeplinkType الحالي:

دع Deeplinker = DeepLinkManager ()
صنف DeepLinkManager {
   fileprivate init () {}
   var var deeplinkType: DeeplinkType؟
}

استنادًا إلى deeplinkType الذي سيقرره التطبيق ، ما الصفحة التي يجب فتحها:

دع Deeplinker = DeepLinkManager ()
صنف DeepLinkManager {
   fileprivate init () {}
   var var deeplinkType: DeeplinkType؟
   / / التحقق من deepling القائمة وتنفيذ العمل
   func checkDeepLink () {
   }
}

سواء كان التطبيق يقوم بتشغيل أو الدخول في وضع المقدمة ، فسوف يقوم باستدعاء أسلوب didBecomeActive appDelegate. في هذا المكان سنبحث عن أي روابط عميقة حالية يمكننا التعامل معها:

تطبيق funcDidBecomeActive (_ application: UIApplication) {
   / / التعامل مع أي deeplink
   Deeplinker.checkDeepLink ()
}

في كل مرة يصبح فيها التطبيق نشطًا ، سيتحقق من وجود رابط عميق لفتح. دعنا ننشئ فئة متصفح ، والتي ستفتح صفحة تطبيق معينة بناءً على DeeplinkType:

class DeeplinkNavigator {
   السماح الثابت بالمشاركة = DeeplinkNavigator ()
   الحرف الخاص () {}
   
   func forwardToDeeplink (_ type: DeeplinkType) {
   }
}

في هذا البرنامج التعليمي ، سنقوم ببساطة بعرض تنبيه مع اسم DeeplinkType الذي تعاملنا معه:

var alertController الخاص = UIAlertController ()
func displayAlert الخاص (العنوان: سلسلة) {
   alertController = UIAlertController (العنوان: العنوان ، الرسالة: nil ، preferenttyle: .alert)
   اسمح لـ okButton = UIAlertAction (title: "Ok" ، النمط: .default ، المعالج: nil)
   alertController.addAction (okButton)
   إذا سمحت vc = UIApplication.shared.keyWindow؟ .rootViewController {
      إذا vc.presentedViewController! = لا شيء {
         alertController.dismiss (الرسوم المتحركة: false ، الإكمال: {
            vc.present (self.alertController ، متحرك: صحيح ، إكمال: لا شيء)
         })
      } آخر {
          vc.present (alertController ، متحرك: صحيح ، إكمال: لا شيء)
      }
   }
}

في forwardToDeeplink ننتقل بين DeeplinkTypes ونقرر ما التنبيه الذي سيتم عرضه:

func forwardToDeeplink (_ type: DeeplinkType) {
   نوع التبديل {
   حالة. النشاط:
      displayAlert (العنوان: "النشاط")
   حالة .الرسائل (.root):
      displayAlert (العنوان: "الرسائل الجذر")
   case .messages (.details (id: let id)):
      displayAlert (title: "Details Details \ (id)")
   الحالة. قائمة جديدة:
      displayAlert (العنوان: "قائمة جديدة")
   case .request (id: let id):
      displayAlert (title: "Request Details \ (id)")
   }
}

ارجع إلى DeepLinkManager واستخدم المستكشف للتعامل مع deepLink:

/ / التحقق من deepling القائمة وتنفيذ العمل
func checkDeepLink () {
   السماح للحراسة deeplinkType = deeplinkType else {
      إرجاع
   }
 
   DeeplinkNavigator.shared.proceedToDeeplink (deeplinkType)
   / / إعادة تعيين deeplink بعد المناولة
   self.deeplinkType = لا شيء // (1)
}
لا تنسَ إعادة تعيين الرابط العميق إلى الصفر (1) بعد استخدامه. وإلا ، فسيتم التعامل مع نفس الرابط مرة أخرى عند فتح التطبيق في المرة القادمة.

الآن نحن بحاجة فقط إلى التحقق مما إذا كان هناك أي ارتباطات عميقة (اختصارات أو ارتباطات عميقة أو إعلامات) يجب معالجتها ، وتحليلها إلى DeeplinkType ومنحهم DeepLinkManager.

أولاً ، يتعين علينا إجراء إعداد أساسي للاختصارات والروابط العميقة والإعلامات.

بينما نريد من DeepLinkManager التعامل مع أي نوع من الروابط العميقة ، تذكر حول SRP (مبدأ المسؤولية الفردية): لن نمزج بين الطرق التي نتبعها في تحليل أنواع مختلفة من الروابط العميقة.

اختصارات

تستخدم الطريقة الشائعة لإنشاء اختصارات ثابتة ملف info.plist. إليك برنامج تعليمي موجز ، إذا كنت تريد التحقق من ذلك.

في حالتنا ، ستكون بعض الاختصارات ديناميكية. لذلك ، سنفعل كل شيء في الكود. تمنحك هذه الطريقة مزيدًا من المرونة والتحكم ، ومن السهل فهمها.

أولاً ، نقوم بإنشاء اختصار. هذه الفئة ستكون مسؤولة فقط عن الاختصارات.

class ShortcutParser {
   ثابت ثابت شارك = ShortcutParser ()
   الحرف الخاص () {}
}

ثم نحتاج إلى تحديد مفاتيح الاختصار المحتملة:

التعداد ShortcutKey: String {
   حالة قائمة جديدة = "com.myApp.newListing"
   نشاط الحالة = "com.myApp.activity"
   رسائل الحالة = "com.MyApp.messages"
}

في ShortcutParser نقوم بإنشاء طريقة registerShortcutsFor ، والتي ستسجل الاختصارات لأنواع المستخدمين المختلفة.

func registerShortcuts (for profileType: ProfileType) {
   اسمح لـ activityIcon = UIApplicationShortcutIcon (templateImageName: "رمز التنبيه")
   واسمحوا نشاطShortcutItem = UIApplicationShortcutItem (اكتب: ShortcutKey.activity.rawValue، localizedTitle: "Activity Recent"، localizedSubtitle: nil، icon: activityIcon، userInfo: nil)
   اسمح لـ messageIcon = UIApplicationShortcutIcon (templateImageName: "Messenger Messenger")
   واسمحوا messageShortcutItem = UIApplicationShortcutItem (اكتب: ShortcutKey.messages.rawValue ، localizedTitle: "Messages"، localizedSubtitle: nil، icon: messageIcon، userInfo: nil)
   UIApplication.shared.shortcutItems = [activityShortcutItem، messageShortcutItem]
تبديل الملف الشخصي
      القضية.
         اسمح newListingIcon = UIApplicationShortcutIcon (templateImageName: "رمز قائمة جديدة")
         اسمحوا newListingShortcutItem = UIApplicationShortcutItem (اكتب: ShortcutKey.newListing.rawValue، localizedTitle: "New List"، localizedSubtitle: nil، icon: newListingIcon، userInfo: nil)
    UIApplication.shared.shortcutItems؟ .append (newListingShortcutItem)
      القضية.
         استراحة
   }
}

نقوم بإنشاء نشاط ShortcutItem و messageShortcutItem لكلا النوعين من الملفات الشخصية. إذا كان المستخدم الحالي مضيفًا ، فإننا نضيف قائمة جديدة ShortcutItem. لكل اختصار ، نستخدم UIApplicationShortcutIcon (سيتم عرض هذا الرمز بجوار عنوان الاختصار عندما تضغط على رمز التطبيق).

سوف نسمي هذه الطريقة من خلال ViewController: عندما يقوم المستخدم بتبديل ملف التعريف ، سيتم إعادة تكوين الاختصارات بناءً على نوع ملف التعريف الجديد:

func configFor (profileType: ProfileType) {
   العنوان = profileType.rawValue
   ShortcutParser.registerShortcuts (لـ: profileType)
}
بالنسبة للاختصارات الثابتة ، من الأفضل تعيين الاختصارات من AppDelegate ، لذلك لا يتعين على التطبيق تحميل ViewController قبل تعيين الاختصارات

بناء التطبيق وتشغيله واختبار سلوكه:

  1. المس بقوة على أيقونة التطبيق لرؤية خيارات الاختصارات
  2. تبديل الملف الشخصي
  3. اضغط على أيقونة التطبيق مرة أخرى لمعرفة مجموعة أخرى من خيارات الاختصارات

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

قم بالتبديل إلى AppDelegate وإضافة أسلوب المفوض performActionForShortcutItem:

// مارك: الاختصارات
تطبيق func (_ application: UIApplication ، performActionFor shortcutItem: UIApplicationShortcutItem، completHandler:escaping (Bool) -> Void) {
}

سوف تكتشف هذه الطريقة متى يتم تشغيل الاختصار ، وسيقوم الاكتمال Handler بإخطار المفوض ما إذا كان يجب التعامل معه أم لا. مرة أخرى ، لن نضع أي منطق اختصار في appDelegate. بدلاً من ذلك ، نقوم بإنشاء طريقة في DeeplinkManager:

discardableResult
func handleShortcut (العنصر: UIApplicationShortcutItem) -> Bool {
   deeplinkType = ... // سنقوم بتحليل العنصر هنا
   إرجاع deeplinkType! = لا شيء
}

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

يخبرdiscardableResult المحول البرمجي بتجاهل قيمة النتيجة إذا لم نستخدمها ، لذلك ليس لدينا تحذير "نتيجة غير مستخدمة"

العودة إلى التطبيقإلغاء وإكمال طريقة performActionFor:

// مارك: الاختصارات
تطبيق func (_ application: UIApplication ، performActionFor shortcutItem: UIApplicationShortcutItem، completHandler:escaping (Bool) -> Void) {
   completHandler (Deeplinker.handleShortcut (العنصر: shortcutItem))
}

آخر شيء نحتاج إلى القيام به هو تحليل عنصر الاختصار إلى DeeplinkType. لدينا بالفعل فئة ShortcutParser ، وهي المسؤولة عن جميع الإجراءات المتعلقة بالاختصارات. أضف طريقة أخرى:

func handleShortcut (_ اختصار: UIApplicationShortcutItem) -> DeeplinkType؟ {
   رمز التبديل اختصار.
   حالة اختصار Key.activity.rawValue:
      عودة. النشاط
   حالة اختصار المفاتيح. رسائل.
      العودة .الرسائل (.root)
   حالة اختصار Key.NewListing.rawValue:
      العودة .قائمة جديدة
   الافتراضي:
      عودة لا شيء
   }
}

الآن ، ارجع إلى DeeplinkManager وأكمل طريقة SHortcut:

discardableResult
func handleShortcut (العنصر: UIApplicationShortcutItem) -> Bool {
   deeplinkType = ShortcutParser.shared.handleShortcut (عنصر)
   إرجاع deeplinkType! = لا شيء
}

هذا كل ما نحتاج إليه للتعامل مع الاختصارات! دعنا نمر بها خطوة بخطوة مرة أخرى. عندما نضغط على أيقونة الاختصار:

  1. يقوم الإجراء المختصرة بتشغيل طريقة appDelegate performActionForShortcutItem
  2. أسلوب performActionForShortcutItem بتمرير ShortcutItem إلى DeeplinkManager
  3. يحاول DeeplinkManager تحليل ShortcutItem إلى DeeplinkType باستخدام ShortcutParser
  4. على applicationDidBecomeActive نقوم بإجراء التحقق من أي DeeplinkTypes
  5. إذا كان DeeplinkType موجودًا (وهذا يعني ، تنجح الخطوة 3) ، فإننا نقوم بالإجراء المناسب باستخدام DeeplinkNavigator
  6. بمجرد معالجة الاختصار ، يعيد DeeplinkManager إعادة تعيين عنصر الاختصار الحالي إلى الصفر ، لذلك لن يتم استخدامه مرة أخرى

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

روابط عميقة

ستتضمن Deeplinks التي سنقوم بمعالجتها التنسيق التالي:

deeplinkTutorial: // رسائل / 1
deeplinkTutorial: // طلب / 1

انسخ وحفظ عناوين URL هذه في "ملاحظات" على جهاز الاختبار الخاص بك. إذا نقرت على أي من الروابط ، فلن يحدث شيء.

إذا كان هذا رابطًا عالميًا ، فسيؤدي النقر فوق الارتباط إلى فتح مستعرض بعنوان URL.

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

سوف يكتشف AppDelegate ما إذا كان التطبيق قد تم فتحه باستخدام عنوان URL لإلغاء الارتباط ، وتشغيل طريقة openUrl:

// MARK: Deeplinks
تطبيق func (_ التطبيق: UIApplication ، عنوان url المفتوح: URL ، الخيارات: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
}

قيمة الإرجاع تخبر المفوض ما إذا كان سيتم فتح عنوان URL أم لا.

إذا كنت تريد دعم الارتباطات العالمية (المقدمة في iOS9) ، فقم أيضًا بإضافة طريقة المفوض التالية:

// مارك: روابط عالمية
تطبيق func (_ application: UIApplication ، تابع userActivity: NSUserActivity ، restorationHandler:escaping ([Any]؟) -> Void) -> Bool {
   إذا كان userActivity.activityType == NSUserActivityTypeBrowsingWeb {
      إذا سمحت لـ url = userActivity.webpageURL {
         
      }
   }
   عودة كاذبة
}
يتم تشغيل ContunueUserActivity أيضًا عند تشغيل التطبيق من خلال عناصر Spotlighs (غير المشمولة في هذا البرنامج التعليمي).

باتباع نفس النمط الذي استخدمناه للاختصارات ، نقوم بإنشاء DeeplinkParser:

class DeeplinkParser {
   السماح الثابت بالمشاركة = DeeplinkParser ()
   الحرف الخاص () {}
}

لتحليل Deeplink ، نقوم بإنشاء طريقة تأخذ URL وتعيد DeeplinkType الاختياري:

func parseDeepLink (_ url: URL) -> DeeplinkType؟ {
   حراسة السماح للمكونات = URLComponents (url: url، resolutionvingAgainstBaseURL: true) ، دع host = components.host else {
      عودة لا شيء
   }
   var pathComponents = components.path.components (separatedBy: "/")
   // المكون الأول فارغ
   pathComponents.removeFirst ()
   تبديل المضيف {
   حالة "الرسائل":
      إذا سمح messageId = pathComponents.first {
         إرجاع DeeplinkType.messages (.details (المعرف: messageId))
      }
   حالة "طلب":
      إذا سمحت requestId = pathComponents.first {
         إرجاع DeeplinkType.request (المعرف: requestId)
      }
   الافتراضي:
      استراحة
   }
   عودة لا شيء
}
لاحظ أن طريقة التحليل هذه ستعتمد على بنية إلغاء الربط ، وأن الحل الخاص بي هو مثال فقط.

الآن يمكننا توصيل هذا المحلل اللغوي بفصل إلغاء الربط الرئيسي. أضف هذه الطريقة في DeeplinkManager:

discardableResult
func handleDeeplink (url: URL) -> Bool {
   deeplinkType = DeeplinkParser.shared.parseDeepLink (url)
   إرجاع deeplinkType! = لا شيء
}

في appDelegate نكمل أساليب openUrl و ContinueUserActivity:

// MARK: Deeplinks
تطبيق func (_ التطبيق: UIApplication ، عنوان url المفتوح: URL ، الخيارات: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
   إرجاع Deeplinker.handleDeeplink (url: url)
}
// مارك: روابط عالمية
تطبيق func (_ application: UIApplication ، تابع userActivity: NSUserActivity ، restorationHandler:escaping ([Any]؟) -> Void) -> Bool {
   إذا كان userActivity.activityType == NSUserActivityTypeBrowsingWeb {
      إذا سمحت لـ url = userActivity.webpageURL {
         إرجاع Deeplinker.handleDeeplink (url: url)
      }
   }
   عودة كاذبة
}

هناك شيء آخر نحتاج إلى فعله: أخبر تطبيقنا عن نوع الارتباط الذي يجب اكتشافه. أضف مقتطف الشفرة هذا إلى ملف info.plist (انقر بزر الماوس الأيمن على info.plist -> فتح باسم -> شفرة المصدر):

<مفتاح> CFBundleURLTypes 
<مجموعة>
   <ديكت>
      <مفتاح> CFBundleURLName 
      <سلسلة> com.deeplinkTut.Deeplink 
      <مفتاح> CFBundleURLSchemes 
      <مجموعة>
         <سلسلة> deeplinkTutorial 
      
   
تأكد من عدم كسر بنية ملف XML.

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

سيؤدي هذا إلى إخبار التطبيق بالكشف عن الروابط فقط بعنوان URL "deeplinkTutorial".

دعنا نذهب من خلال جميع الخطوات مرة أخرى:

  1. صنابير المستخدم على deeplink خارج التطبيق
  2. يكتشف AppDelegate الارتباط ويقوم بتشغيل طريقة المفوض openUrl (أو طريقة المفوض ContinUserActivity للارتباطات العالمية)
  3. أسلوب openUrl يمرر الرابط إلى Deeplink Manager
  4. يحاول Deeplink Manager تحليل الارتباط إلى Deeplink Type باستخدام DeeplinkParser
  5. على applicationDidBecomeActive نقوم بإجراء التحقق من أي DeeplinkTypes
  6. إذا كان DeeplinkType موجودًا (وهذا يعني ، تنجح الخطوة 4) ، فإننا نقوم بالإجراء المناسب باستخدام DeeplinkNavigator
  7. بمجرد معالجة الاختصار ، يعيد DeeplinkManager إعادة تعيين عنصر الاختصار الحالي إلى الصفر ، لذلك لن يتم استخدامه مرة أخرى

شغّل التطبيق ، وحاول فتح الرابط الذي قمت بحفظه في ملاحظاتك:

إخطارات

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

لإرسال إشعارات APNS ، يمكنك استخدام خادم محلي و PusherAPI (هذه هي إحدى الطرق البسيطة).

سنغطي فقط الجزء بين النقر على إشعار الدفع ورؤية النتيجة.

عندما يتم إغلاق التطبيق أو تشغيله على الخلفية أكثر ، فإن النقر على شعار الإشعارات سيؤدي إلى تشغيل أسلوب didReceiveRemoteNotification appelegate:

تطبيق func (_ application: UIApplication، didReceiveRemoteNotification userInfo: [AnyHashable: Any]، fetchCompletionHandler finishHandler:escaping (UIBackgroundFetchResult) -> Void) {
   
}
سيتم أيضًا تشغيل هذه الطريقة عندما يتلقى التطبيق إشعارًا بالدفع أثناء تشغيله في وضع المقدمة. نظرًا لأننا نتفحص السيناريوهات فقط عندما تريد فتح التطبيق على صفحة معينة ، فلن نغطي معالجة إشعارات الوضع الأمامي.

للتعامل مع الإخطارات ، سنقوم بإنشاء NotificationParser:

Classification NotificationParser {
   السماح الثابت بالمشاركة = NotificationParser ()
   الحرف الخاص () {}
   func handleNotification (_ userInfo: [AnyHashable: Any]) -> DeeplinkType؟ {
      عودة لا شيء
   }
}

الآن يمكننا توصيل هذه الطريقة بمدير Deeplink:

func handleRemoteNotification (_ الإعلام: [AnyHashable: Any]) {
   deeplinkType = NotificationParser.shared.handleNotification (إعلام)
}

وأكمل appDelegate didReceiveRemoteNotification طريقة:

تطبيق func (_ application: UIApplication، didReceiveRemoteNotification userInfo: [AnyHashable: Any]، fetchCompletionHandler finishHandler:escaping (UIBackgroundFetchResult) -> Void) {
   Deeplinker.handleRemoteNotification (المعلومات حول المستخدم)
}

الخطوة الأخيرة هي إنهاء طريقة التحليل في NotificationParser. سيعتمد هذا على هيكل الإشعار الخاص بك ، لكن تقنية التحليل الأساسية ستكون مماثلة:

func handleNotification (_ userInfo: [AnyHashable: Any]) -> DeeplinkType؟ {
   إذا دع البيانات = userInfo ["data"] كما؟ [السلسلة: أي] {
      إذا سمح messageId = data ["messageId"] كما؟ خيط {
         إرجاع DeeplinkType.messages (.details (المعرف: messageId))
      }
   }
   عودة لا شيء
}

إذا قمت بتكوين التطبيق لدعم إشعارات الدفع وتريد اختباره ، فإليك الإشعار الذي أستخدمه لتوصيل رسالة:

apns: {
    aps: {
        محزر: {
            العنوان: "رسالة جديدة!" ،
            العنوان الفرعي: "" ،
            الجسم: "مرحبا!"
        }،
        "محتوى قابل للتغيير": 0 ،
        الفئة: "انتهازي"
    }،
    البيانات: {
        "messageId": "1"
    }
}
أنا أستخدم خادم NodeJS محلي و Pusher API لإرسال الإشعارات في هذا البرنامج التعليمي. يستغرق الإعداد بضع دقائق فقط ويتطلب المعرفة الأساسية بـ NodeJS أو بعض مهارات لصق النسخ.

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

إليك ما يحدث خلف الكواليس:

  1. عند النقر فوق الإخطار ، يقوم التطبيق بتشغيل طريقة تفويض didReceiveRemoteNotification
  2. يقوم didReceiveRemoteNotification بتمرير معلومات الإشعار إلى مدير Deeplink
  3. يحاول Deeplink Manager تحليل معلومات المستخدم للإعلام إلى نوع Deeplink باستخدام NotificationParser
  4. على applicationDidBecomeActive نقوم بإجراء التحقق من أي DeeplinkTypes
  5. إذا كان DeeplinkType موجودًا (وهذا يعني ، تنجح الخطوة 3) ، فإننا نقوم بالإجراء المناسب باستخدام DeeplinkNavigator
  6. بمجرد معالجة الاختصار ، يعيد DeeplinkManager إعادة تعيين عنصر الاختصار الحالي إلى الصفر ، لذلك لن يتم استخدامه مرة أخرى

باستخدام هذا النهج ، يمكنك بسهولة إضافة أو تعديل أي من العناصر دون تغييرات كبيرة في التعليمات البرمجية. والأهم من ذلك ، يمكنك تحليل أي deeplink باستخدام المحلل اللغوي المناسب. على سبيل المثال ، لإضافة "طلب جديد" في معالج الإشعارات ، تحتاج فقط إلى تعديل handleNotification method في NotificationParser:

func handleNotification (_ userInfo: [AnyHashable: Any]) -> DeeplinkType؟ {
   إذا دع البيانات = userInfo ["data"] كما؟ [السلسلة: أي] {
      إذا سمح messageId = data ["messageId"] كما؟ خيط {
         إرجاع DeeplinkType.messages (.details (المعرف: messageId))
      }
      إذا سمحت requestId = data ["requestId"] كما؟ خيط {
         إرجاع DeeplinkType.request (.details (المعرف: requestId))
      }
   }
   عودة لا شيء
}
لاحظ أننا لا نستخدم didFinishLaunchingWithOptions لأي من هذه الروابط. كل شيء يتم معالجته بواسطة applicationDidBecomeActive.

تهانينا! الآن يحتوي التطبيق الخاص بك على دعم عالمي من الاختصارات وإلغاء الارتباطات والإشعارات!

تحقق من المشروع النهائي هنا:

شكرا للقراءة! إذا كنت تحب هذا البرنامج التعليمي ، فيرجى الضغط على .

أنا أكتب أيضًا لمدونة American Express Engineering. تحقق من أعمالي الأخرى وأعمال زملائي الموهوبين في AmericanExpress.io.