النشر والاشتراك

‫Nearby Messages API هي واجهة برمجة تطبيقات للنشر والاشتراك تتيح للأجهزة المجاورة مبادلة حزم بيانات صغيرة. بعد أن ينشر أحد الأجهزة رسالة، يمكن للأجهزة المجاورة تلقّي الرسالة. يجب إبقاء حجم الرسالة صغيرًا إلى حدٍ ما للحفاظ على الأداء الجيد. هذه الخدمة غير مخصّصة لتبادل ملفّات أكبر حجمًا، مثل الصور والفيديوهات.

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

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

تعمل هذه المكتبة على نظام التشغيل iOS 7 والإصدارات الأحدث، ويتم إنشاؤها باستخدام حزمة تطوير البرامج (SDK) لنظام التشغيل iOS 8.

إنشاء مدير رسائل

تُنشئ هذه التعليمة البرمجية عنصرًا لإدارة الرسائل، ما يتيح لك النشر والاشتراك. لا تتم مصادقة تبادل الرسائل، لذا عليك تقديم مفتاح واجهة برمجة تطبيقات متاح للجميع لنظام التشغيل iOS. يمكنك إنشاء حساب باستخدام إدخال Google Developers Console لمشروعك.

Objective-C

#import <GNSMessages.h>

GNSMessageManager *messageManager =
    [[GNSMessageManager alloc] initWithAPIKey:@"API_KEY"];

Swift

let messageManager = GNSMessageManager(APIKey: "API_KEY")

نشر رسالة

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

Objective-C

id<GNSPublication> publication =
    [messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]];

Swift

let publication =
    messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)))

الاشتراك في الرسائل

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

يتمّ استدعاء معالِج الرسالة التي تمّ العثور عليها عند رصد الأجهزة المجاورة التي تنشر الرسائل. يتمّ استدعاء معالِج فقدان الرسالة عندما يتوقف رصد الرسالة (يعني ذلك أنّ الجهاز خرج من النطاق أو لم يعُد ينشر الرسالة).

Objective-C

id<GNSSubscription> subscription =
    [messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) {
      // Add the name to a list for display
    }
    messageLostHandler:^(GNSMessage *message) {
      // Remove the name from the list
    }];

Swift

let subscription =
    messageManager.subscription(messageFoundHandler: { (message: GNSMessage?) in
      // Add the name to a list for display
    },
    messageLostHandler: { (message: GNSMessage?) in
      // Remove the name from the list
    })

وسائط "الحملات أثناء التصفّح"

سيتم تلقائيًا استخدام كلتا المادتَين (الصوت والبلوتوث) لاكتشاف الأجهزة المجاورة، وستُجري كلتا المادتَين عمليات البث والبحث. في بعض الحالات، عليك إضافة الإدخالات التالية إلى Info.plist تطبيقك:

  • إذا كان تطبيقك يفحص باستخدام الصوت، أضِف NSMicrophoneUsageDescription، وهي سلسله تصف سبب استخدام الميكروفون. على سبيل المثال، "يرصد الميكروفون الرموز المميّزة المجهولة المصدر من الأجهزة المجاورة".

  • إذا كان تطبيقك يبثّ البيانات باستخدام تقنية BLE، أضِف NSBluetoothPeripheralUsageDescription، وهي سلسلة تصف سبب عرض إعلاناتك على تقنية BLE. على سبيل المثال، "يتم عرض رمز مميّز مجهول عبر البلوتوث لاكتشاف الأجهزة المجاورة".

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

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

Objective-C

id<GNSPublication> publication = [messageManager publicationWithMessage:message
    paramsBlock:^(GNSPublicationParams *params) {
      params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
        params.discoveryMediums = kGNSDiscoveryMediumsAudio;
        params.discoveryMode = kGNSDiscoveryModeScan;
      }];
    }];

Swift

let publication = messageManager.publication(with: message,
    paramsBlock: { (params: GNSPublicationParams?) in
      guard let params = params else { return }
      params.strategy = GNSStrategy(paramsBlock: { (params: GNSStrategyParams?) in
        guard let params = params else { return }
        params.discoveryMediums = .audio
        params.discoveryMode = .scan
      })
    })

تفعيل ميزة تسجيل معلومات تصحيح الأخطاء

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

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

Objective-C

[GNSMessageManager setDebugLoggingEnabled:YES];

Swift

GNSMessageManager.setDebugLoggingEnabled(true)

تتبُّع حالة إذن "الأجهزة المجاورة"

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

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

Objective-C

GNSPermission *nearbyPermission = [[GNSPermission alloc] initWithChangedHandler:^(BOOL granted) {
  // Update the UI here
}];

Swift

let nearbyPermission = GNSPermission(changedHandler: { (granted: Bool) in
  // Update the UI here
})

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

في ما يلي مثال على كيفية الحصول على حالة الإذن وضبطها.

Objective-C

BOOL permissionState = [GNSPermission isGranted];
[GNSPermission setGranted:!permissionState];  // toggle the state

Swift

let permissionState = GNSPermission.isGranted()
GNSPermission.setGranted(!permissionState)  // toggle the state

تتبُّع إعدادات المستخدم التي تؤثّر في ميزة "الاقتران عن قرب"

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

Objective-C

GNSMessageManager *messageManager = [[GNSMessageManager alloc]
    initWithAPIKey:API_KEY
       paramsBlock:^(GNSMessageManagerParams *params) {
         params.microphonePermissionErrorHandler = ^(BOOL hasError) {
           // Update the UI for microphone permission
         };
         params.bluetoothPowerErrorHandler = ^(BOOL hasError) {
           // Update the UI for Bluetooth power
         };
         params.bluetoothPermissionErrorHandler = ^(BOOL hasError) {
           // Update the UI for Bluetooth permission
         };
}];

Swift

let messageManager = GNSMessageManager(
         APIKey: API_KEY,
    paramsBlock: { (params: GNSMessageManagerParams?) in
      guard let params = params else { return }
      params.microphonePermissionErrorHandler = { (hasError: Bool) in
        // Update the UI for microphone permission
      }
      params.bluetoothPowerErrorHandler = { (hasError: Bool) in
        // Update the UI for Bluetooth power
      }
      params.bluetoothPermissionErrorHandler = { (hasError: Bool) in
        // Update the UI for Bluetooth permission
      }
    })

إلغاء مربّع حوار إذن "الأجهزة المجاورة"

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

إذا كنت تريد توفير مربّع حوار مخصّص "للتحقّق من التوافق"، اضبط المَعلمة permissionRequestHandler على كتلة مخصّصة في مَعلمات النشر أو الاشتراك. يجب أن تستدعي الكتلة المخصّصة permissionHandler بعد أن يردّ المستخدم. يوضّح المقتطف التالي كيفية إجراء ذلك لنشرة:

Objective-C

id<GNSPublication> publication =
    [messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]
                               paramsBlock:^(GNSPublicationParams *params) {
                                 params.permissionRequestHandler = ^(GNSPermissionHandler permissionHandler) {
                                   // Show your custom dialog here.
                                   // Don't forget to call permissionHandler() with YES or NO when the user dismisses it.
                                 };
                               }];

Swift

let publication =
    messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)),
        paramsBlock: { (params: GNSPublicationParams?) in
          guard let params = params else { return }
          params.permissionRequestHandler = { (permissionHandler: GNSPermissionHandler?) in
            // Show your custom dialog here.
            // Don't forget to call permissionHandler() with true or false when the user dismisses it.
          }
        })

عملية في الخلفية

يمكن أن تعمل الاشتراكات والمنشورات التي تستخدم تقنية BLE لاكتشاف الأجهزة في الخلفية. في ما يلي بعض النقاط التي يجب أخذها في الاعتبار عند اتخاذ قرار استخدام وضع "الخلفية":

  • يجب أن تستخدم العمليات التي تعمل في الخلفية وسيط BLE فقط، ولا يُسمح باستخدام الصوت.
  • هناك تكلفة إضافية للبطارية عند استخدام تقنية BLE في الخلفية. تكون التكلفة منخفضة، ولكن عليك قياسها قبل اتخاذ قرار استخدام وضع الخلفية.
  • سيطلب نظام التشغيل iOS من المستخدم الإذن بعرض الإعلانات عبر تقنية BLE في الخلفية.

لإضافة وضع "العرض في الخلفية" إلى نشرة أو اشتراك، اتّبِع الخطوات التالية المُضافة:

  • فعِّل وضع "الخلفية" وتقنية البلوتوث منخفض الطاقة فقط في النشر أو الاشتراك من خلال إدخال عنصر GNSStrategy تم ضبطه بشكل صحيح. يوضّح المقتطف التالي كيفية إجراء ذلك لاشتراك:

    Objective-C

    id<GNSSubscription> subscription =
        [messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) {
          // Add the name to a list for display
        }
        messageLostHandler:^(GNSMessage *message) {
          // Remove the name from the list
        }
        paramsBlock:^(GNSSubscriptionParams *params) {
          params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
            params.allowInBackground = YES;
            params.discoveryMediums = kGNSDiscoveryMediumsBLE;
          }];
        }];
    

    Swift

    let subscription =
        messageManager.subscription(messageFoundHandler: { (message: GNSMessage?) in
          // Add the name to a list for display
        },
        messageLostHandler: { (message: GNSMessage?) in
          // Remove the name from the list
        },
        paramsBlock:{ (params: GNSSubscriptionParams?) in
          guard let params = params else { return }
          params.strategy = GNSStrategy(paramsBlock: { (params: GNSStrategyParams?) in
            guard let params = params else { return }
            params.allowInBackground = true
            params.discoveryMediums = .BLE
          })
        })
    

  • أضِف الإدخالات التالية إلى Info.plist تطبيقك:

    • UIBackgroundModes إدخال:

      • bluetooth-central للبحث عن الأجهزة التي تتضمّن بلوتوث منخفض الطاقة في الخلفية لا يلزم استخدام هذا الخيار إلا عندما يتضمّن وضع "التصفّح" عملية مسح، وهو ما يحدث تلقائيًا.
      • bluetooth-peripheral للإعلانات منخفضة الطاقة للبلوتوث في الخلفية لا يلزم تحديد هذه السمة إلا عندما يتضمّن وضع الاكتشاف البث، وهو يتم تلقائيًا.
    • NSBluetoothPeripheralUsageDescription سلسلة تصف سبب نشر إعلاناتك على BLE على سبيل المثال، "يتم عرض رمز مميّز مجهول عبر البلوتوث لاكتشاف الأجهزة المجاورة". اطّلِع على مستندات Apple لمعرفة التفاصيل.

  • يمكن للنظام إغلاق تطبيقك في أي وقت عندما يكون في الخلفية. إذا كان وضع الخلفية هو إعداد يمكن للمستخدم تفعيله أو إيقافه، يجب أن يؤدي تطبيقك إلى ما يلي:

    • احفظ قيمة وضع الخلفية على NSUserDefaults كلما غيّرها المستخدِم.
    • عند بدء التشغيل، اقرأها من NSUserDefaults واستعدّ المحتوى المعروض في "الاقتراحات" و/أو الاشتراكات إذا كان وضع "التشغيل في الخلفية" مفعّلاً.

الإشعارات التي تعمل في الخلفية

إذا كنت تريد أن يُرسِل تطبيقك إشعارًا إلى المستخدم عندما يتلقّى اشتراك رسالة في الخلفية، يمكنك استخدام الإشعارات المحلية.

اتّبِع الخطوات التالية لإضافتها إلى تطبيقك:

  • التسجيل للحصول على إشعارات على الجهاز عند بدء التشغيل:

    Objective-C

    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
      [[UIApplication sharedApplication] registerUserNotificationSettings:
          [UIUserNotificationSettings settingsForTypes:
              UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound
                                            categories:nil]];
    }
    

    Swift

    UIApplication.shared.registerUserNotificationSettings(
        UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil))
    

  • أرسِل إشعارًا محليًا في معالِج العثور على الرسالة في اشتراكك:

    Objective-C

    GNSMessageHandler myMessageFoundHandler = ^(GNSMessage *message) {
        // Send a local notification if not in the foreground.
        if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
          UILocalNotification *localNotification = [[UILocalNotification alloc] init];
          localNotification.alertBody = @"Message received";
          [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
        }
        // Process the new message...
      };
    

    Swift

    let myMessageFoundHandler: GNSMessageHandler = { (message: GNSMessage?) in
      // Send a local notification if not in the foreground.
      if UIApplication.shared.applicationState != .active {
        let localNotification = UILocalNotification()
        localNotification.alertBody = "Message received"
        UIApplication.shared.presentLocalNotificationNow(localNotification)
      }
      // Process the new message...
    }