קבלת הודעות ב-Beacon

האפליקציה יכולה להירשם להודעות משובלן (beacon) של Bluetooth עם צריכת אנרגיה נמוכה (BLE) באמצעות אותו מנגנון שמשמשים להרשמה להודעות שפורסמו על ידי מכשירים אחרים בקרבת מקום.

כברירת מחדל, מינויים לחיישנים פועלים רק כשהאפליקציה פועלת בחזית. כשהאפליקציה עוברת לרקע, המינויים מפסיקים באופן אוטומטי לסרוק אחר סמנים. במאמר סריקה ברקע מוסבר איך מפעילים סריקה ברקע.

כדי להירשם לקבלת עדכונים על סמנים, מגדירים את הפרמטר deviceTypesToDiscover לערך kGNSDeviceBLEBeacon בפרמטרים של המינוי. קטע הקוד הבא מראה איך עושים את זה:

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
    })

המינוי שלמעלה מזהה רק סמנים שבבעלות הפרויקט שלכם, ומקבל את כל ההודעות מהסמנים האלה. אם רוצים לקבל הודעות מסמנים שנרשמו במרחב שמות אחר, אפשר להעביר את מרחב השמות בפרמטרים של המינוי. באופן דומה, אם רוצים לקבל הודעות מסוג ספציפי, אפשר גם להעביר סוג הודעה לסינון. קטע הקוד הבא מראה איך עושים את זה:

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.messageNamespace = @"com.mycompany.mybeaconservice";
                              params.type = @"mybeacontype";
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.messageNamespace = "com.mycompany.mybeaconservice"
      params.type = "mybeacontype"
    })

כברירת מחדל, מינוי לחיישנים סורק את שני סוגי החיישנים, Eddystone ו-iBeacon. כשהסריקה של iBeacon מופעלת, המשתמשים מתבקשים לתת לאפליקציה הרשאה להשתמש בנתוני המיקום שלהם. קובץ Info.plist של האפליקציה חייב לכלול את המפתח NSLocationWhenInUseUsageDescription עם הסבר קצר לגבי הסיבה לשימוש במיקום. פרטים נוספים זמינים במסמכי התיעוד של Apple.

אם רוצים לסרוק רק סמנים של Eddystone, אפשר להשבית את הסריקה של iBeacon ב-GNSBeaconStrategy, ומערכת iOS לא תבקש מהמשתמש הרשאה להשתמש במיקום. קטע הקוד הבא מראה איך להשבית את הסריקה של iBeacon במינוי המקורי שלמעלה:

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.beaconStrategy =
                                  [GNSBeaconStrategy strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                    params.includeIBeacons = NO;
                                  };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.beaconStrategy =
          GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
            params.includeIBeacons = false
          })
    })

כברירת מחדל, הסריקה בצריכת אנרגיה נמוכה מופעלת, ולפעמים היא עלולה לגרום לזמני אחזור ארוכים במיוחד כשמחפשים סמנים של Eddystone. כשמצב צריכת האנרגיה הנמוכה מושבת, המערכת משתמשת בסריקה של iBeacon כדי למצוא סמנים של Eddystone, וכך לצמצם את זמני האחזור האלה. עם זאת, הפעולה הזו גורמת לצריכה מוגברת של הסוללה, ומערכת iOS תבקש מהמשתמש הרשאה להשתמש במיקום.

קטע הקוד הבא מראה איך להשבית את מצב צריכת האנרגיה הנמוכה במהלך הסריקה אחר סמלי Eddystone.

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.beaconStrategy =
                                  [GNSBeaconStrategy strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                    params.includeIBeacons = NO;
                                    params.lowPowerPreferred = NO;
                                  };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.beaconStrategy =
          GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
            params.includeIBeacons = false
            params.lowPowerPreferred = false
          })
    })

כשמחפשים סמלי iBeacon, תיבת הדו-שיח של הרשאת המיקום ב-iOS מופיעה אחרי תיבת הדו-שיח של הרשאת 'סמלי Nearby'. אם רוצים לשנות את תיבת הדו-שיח הזו (לדוגמה, כדי להציג תיבת דו-שיח 'לפני ההמראה' שבה מוסבר למה נדרשת הרשאת מיקום), מגדירים את permissionRequestHandler כבלוק מותאם אישית בפרמטרים של המינוי. קטע הקוד הבא מראה איך עושים את זה:

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.permissionRequestHandler = ^(GNSPermissionHandler permissionHandler) {
                                // Show your custom dialog here, and don't forget to call permissionHandler after it is dismissed
                                permissionHandler(userGavePermission);
                              };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.permissionRequestHandler = { (permissionHandler: GNSPermissionHandler!) in
        // Show your custom dialog here, and don't forget to call permissionHandler after it is dismissed
        permissionHandler(userGavePermission);
      }
    })

סריקת רקע

מכיוון שסריקת הסמנים מתבצעת באמצעות BLE, היא יכולה לפעול ברקע. לפני שאתם מחליטים להשתמש במצב רקע, כדאי לדעת כמה דברים:

  • יש עלות נוספת של סוללה ל-BLE ברקע. העלות נמוכה, אבל כדאי למדוד אותה לפני שמחליטים להשתמש במצב רקע.
  • אם הסריקה של iBeacon מופעלת או שמצב צריכת החשמל הנמוכה מושבת, מערכת iOS תבקש מהמשתמש הרשאה להשתמש במיקום ברקע.

כדי להפעיל את הסריקה של הסמנים ברקע, פועלים לפי השלבים הנוספים הבאים:

  • כדי להפעיל את מצב הרקע במינוי, מעבירים אובייקט GNSBeaconStrategy שהוגדר בצורה נכונה. קטע הקוד הבא מראה איך עושים את זה:

    Objective-C

    id<GNSSubscription> beaconSubscription = [messageManager
        subscriptionWithMessageFoundHandler:myMessageFoundHandler
                         messageLostHandler:myMessageLostHandler
                                paramsBlock:^(GNSSubscriptionParams *params) {
                                  params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                                  params.beaconStrategy = [GNSBeaconStrategy
                                      strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                        params.allowInBackground = YES;
                                      }];
                                }];
    

    Swift

    let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
        myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
        paramsBlock: { (params: GNSSubscriptionParams!) in
          params.deviceTypesToDiscover = .BLEBeacon
          params.beaconStrategy =
              GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
                params.allowInBackground = true
              })
        })
    

  • מוסיפים את הרשומות הנדרשות ל-Info.plist של האפליקציה:

    • רשומות UIBackgroundModes:

      • bluetooth-central לסריקה של BLE ברקע.
      • location לסריקה של iBeacon ברקע באמצעות מצב הספק גבוה. אפשר להשמיט את השדה הזה אם מבצעים סריקה בעוצמה נמוכה רק כדי לאתר סמנים של Eddystone.
    • מחרוזת NSLocationAlwaysUsageDescription שמתארת למה אתם מתכוונים לעקוב אחרי המיקום של המשתמש ברקע. לדוגמה, "המיקום שלך נדרש כדי לסרוק אחר סמנים ברקע". פרטים נוספים זמינים במסמכי התיעוד של Apple. אפשר להשמיט את השדה הזה אם מבצעים סריקת אנרגיה נמוכה רק למכשירי Eddystone.

  • האם המשתמש יכול להפעיל או להשבית את הסריקה ברקע באפליקציה? במקרה כזה, צריך לשמור את הערך של מצב הרקע בתור NSUserDefaults, כי מערכת iOS יכולה להרוג את האפליקציה בכל שלב בזמן שהיא פועלת ברקע. האפליקציה צריכה לבצע את הפעולות הבאות:

    • שומרים את הערך של מצב הרקע ב-NSUserDefaults בכל פעם שהמשתמש משנה אותו.
    • בזמן ההפעלה, קוראים אותו מ-NSUserDefaults ומשחזרים את המינוי לחיישן אם מצב הרקע מופעל.

התראות ברקע

אם אתם רוצים שהאפליקציה תודיע למשתמש כשהיא תזהה סמנים ברקע, תוכלו להשתמש בהתראות מקומיות. פרטים נוספים זמינים במאמר התראות ברקע.