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

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

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

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

تعمل هذه المكتبة على iOS 7 والإصدارات الأحدث، ويتم إنشاؤها باستخدام حزمة تطوير البرامج لنظام التشغيل 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
      })
    })

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

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

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

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

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

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

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 block بعد أن يردّ المستخدم. يوضّح المقتطف التالي كيفية تنفيذ ذلك لمنشور:

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 فقط، ولا تتوافق مع الصوت.
  • هناك تكلفة إضافية للبطارية عند استخدام تقنية البلوتوث المنخفض الطاقة في الخلفية. التكلفة منخفضة، ولكن عليك قياسها قبل اتخاذ قرار بشأن استخدام وضع الخلفية.
  • سيطلب نظام التشغيل 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 تصف سبب عرض الإعلانات على البلوتوث المنخفض الطاقة. على سبيل المثال، "يتم عرض رمز مميّز مجهول الهوية عبر البلوتوث لاكتشاف الأجهزة المجاورة". لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات Apple.

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

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

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

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

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

  • تسجيل الإشعارات المحلية عند بدء التشغيل:

    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...
    }