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

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

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

כדי להירשם ל-beacons, מגדירים את הפרמטר 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
    })

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

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"
    })

כברירת מחדל, מינוי ל-Beacons סורק את שני סוגי ה-Beacons, ‏ 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
          })
    })

כשסורקים iBeacons, לפני תיבת הדו-שיח של הרשאת המיקום ב-iOS מופיעה תיבת הדו-שיח של הרשאת הגישה ל'מכשירים בקרבת מקום'. אם רוצים לשנות את תיבת הדו-שיח הזו (לדוגמה, כדי להציג תיבת דו-שיח מקדימה שמסבירה למה נדרשת הרשאת מיקום), צריך להגדיר את 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 ברקע. העלות נמוכה, אבל כדאי למדוד אותה לפני שמחליטים להשתמש במצב רקע.
  • מערכת iOS תבקש מהמשתמש הרשאה להשתמש במיקום ברקע אם הסריקה של iBeacon מופעלת או אם מצב צריכת חשמל נמוכה מושבת.

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

  • כדי להפעיל את מצב הרקע במינוי, צריך להעביר אובייקט 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 entries:

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

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

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

התראות ברקע

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