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
، وهو سلسلة نصية تصف سبب عرض الإعلانات على تقنية البلوتوث المنخفض الطاقة. على سبيل المثال، "يتم عرض رمز مميز مجهول الهوية عبر البلوتوث لاكتشاف الأجهزة المجاورة".
في بعض الحالات، قد يحتاج تطبيقك إلى استخدام إحدى الوسيلتين فقط، وقد لا يحتاج إلى إجراء كل من البث والبحث على تلك الوسيلة.
على سبيل المثال، لا يحتاج تطبيق مصمّم للاتصال بجهاز استقبال البث الذي يبث الصوت فقط إلى إجراء عملية البحث عن الأجهزة باستخدام الصوت. تعرض المقتطفة التالية كيفية نشر رسالة إلى جهاز فك التشفير هذا باستخدام ميزة البحث عن المحتوى من خلال المسح الصوتي فقط:
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
تتبُّع إعدادات المستخدم التي تؤثر في ميزة "المشاركة عن قرب"
إذا رفض المستخدم منح إذن استخدام الميكروفون أو البلوتوث، أو إذا أوقف البلوتوث، لن تعمل ميزة "الأجهزة المجاورة" بشكل جيد أو قد لا تعمل على الإطلاق. يجب أن يعرض تطبيقك رسالة في هذه الحالات لتنبيه المستخدم إلى أنّ عمليات ميزة "الأجهزة المجاورة" معطّلة. تعرض المقتطفة البرمجية التالية كيفية تتبُّع حالة إعدادات المستخدم هذه من خلال تمرير معالِجات عند إنشاء أداة إدارة الرسائل:
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 فقط، ولا تتوافق مع الصوت.
- هناك تكلفة إضافية للبطارية عند استخدام تقنية البلوتوث المنخفض الطاقة في الخلفية. التكلفة منخفضة، ولكن عليك قياسها قبل اتخاذ قرار بشأن استخدام وضع الخلفية.
- سيطلب نظام التشغيل 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
للبحث عن أجهزة BLE في الخلفية مطلوب فقط عندما يتضمّن وضع الاكتشاف عملية المسح، وهو ما يحدث تلقائيًا. bluetooth-peripheral
للإعلانات منخفضة الطاقة للبلوتوث في الخلفية يجب توفير هذا الإذن فقط عندما يتضمّن وضع الاكتشاف البث، وهو ما يحدث تلقائيًا.
-
NSBluetoothPeripheralUsageDescription
سلسلة تصف سبب عرض الإعلانات على البلوتوث المنخفض الطاقة. على سبيل المثال، "يتم الإعلان عن رمز مميز مجهول الهوية عبر البلوتوث للعثور على الأجهزة المجاورة". لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات 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... }