รับข้อความบีคอน

แอปของคุณสามารถสมัครรับข้อความจากบีคอน Bluetooth Low Energy (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"
    })

โดยค่าเริ่มต้น การสมัครรับข้อมูลบีคอนจะสแกนหาบีคอนทั้ง 2 ประเภท ได้แก่ 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 จะแสดงก่อนกล่องโต้ตอบสิทธิ์เข้าถึงอุปกรณ์ใกล้เคียง หากต้องการลบล้างกล่องโต้ตอบนี้ (เช่น เพื่อแสดงกล่องโต้ตอบ "ก่อนบิน" ที่อธิบายเหตุผลที่ต้องมีสิทธิ์เข้าถึงตำแหน่ง) ให้ตั้งค่า 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 และกู้คืนการสมัครรับข้อมูลบีคอนหากเปิดใช้โหมดเบื้องหลัง

การแจ้งเตือนในเบื้องหลัง

หากต้องการให้แอปแจ้งเตือนผู้ใช้เมื่อค้นพบบีคอนขณะที่แอปทำงานใน เบื้องหลัง คุณสามารถใช้ การแจ้งเตือนในเครื่องได้ ดูรายละเอียดได้ที่ การแจ้งเตือนในเบื้องหลัง