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

האפליקציה יכולה להירשם להודעות של משואות בטכנולוגיית Bluetooth עם צריכת אנרגיה נמוכה (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 רשומות:

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

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

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

התראות ברקע

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