Nhận tin nhắn báo hiệu

Ứng dụng của bạn có thể đăng ký nhận thông báo từ beacon Bluetooth năng lượng thấp (BLE) bằng chính cơ chế dùng để đăng ký nhận thông báo do các thiết bị lân cận khác đăng.

Theo mặc định, các dịch vụ đăng ký beacon chỉ hoạt động khi ứng dụng của bạn ở nền trước. Khi ứng dụng chuyển sang chế độ nền, các dịch vụ thuê bao sẽ tự động ngừng quét các beacon. Hãy xem phần Quét ở chế độ nền để biết thông tin chi tiết về cách bật tính năng quét ở chế độ nền.

Để đăng ký nhận thông báo từ các beacon, hãy đặt tham số deviceTypesToDiscover thành kGNSDeviceBLEBeacon trong các tham số đăng ký. Đoạn mã sau đây minh hoạ cách thực hiện việc này:

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

Dịch vụ thuê bao nêu trên chỉ phát hiện các beacon thuộc dự án của bạn và nhận tất cả tin nhắn từ các beacon đó. Nếu muốn nhận thông báo từ các beacon đã đăng ký bằng một không gian tên khác, bạn có thể truyền một không gian tên trong các tham số đăng ký. Tương tự, nếu muốn một loại thông báo cụ thể, bạn cũng có thể truyền một loại thông báo để lọc. Đoạn mã sau đây cho biết cách thực hiện việc này:

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

Theo mặc định, một gói thuê bao báo hiệu sẽ quét cả hai loại báo hiệu, Eddystone và iBeacon. Khi bạn bật tính năng quét iBeacon, người dùng sẽ được nhắc cấp quyền cho ứng dụng sử dụng dữ liệu vị trí của họ. Info.plist của ứng dụng phải có khoá NSLocationWhenInUseUsageDescription kèm theo lời giải thích ngắn gọn về lý do sử dụng vị trí. Hãy xem tài liệu của Apple để biết thông tin chi tiết.

Nếu chỉ muốn quét các beacon Eddystone, bạn có thể tắt tính năng quét iBeacon trong GNSBeaconStrategy và iOS sẽ không yêu cầu người dùng cấp quyền sử dụng vị trí. Đoạn mã sau đây cho biết cách tắt tính năng quét iBeacon cho gói thuê bao ban đầu ở trên:

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

Theo mặc định, tính năng quét ở chế độ nguồn điện thấp sẽ được bật. Đôi khi, tính năng này có thể dẫn đến độ trễ lớn khi tìm thấy các beacon Eddystone. Khi chế độ nguồn điện thấp bị tắt, tính năng quét iBeacon sẽ được dùng để giúp tìm các beacon Eddystone, nhờ đó có thể giảm độ trễ này. Tuy nhiên, điều này sẽ làm tăng mức sử dụng pin và iOS sẽ yêu cầu người dùng cho phép sử dụng vị trí.

Đoạn mã sau cho biết cách tắt chế độ nguồn điện thấp khi quét các beacon 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
          })
    })

Khi quét iBeacon, hộp thoại cấp quyền truy cập thông tin vị trí trên iOS sẽ xuất hiện trước hộp thoại cấp quyền cho thiết bị lân cận. Nếu bạn muốn ghi đè hộp thoại này (ví dụ: để cung cấp một hộp thoại "kiểm tra trước khi bay" giải thích lý do cần có quyền truy cập vị trí), hãy đặt permissionRequestHandler thành một khối tuỳ chỉnh trong các tham số đăng ký. Đoạn mã sau đây cho biết cách thực hiện việc này:

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

Quét ở chế độ nền

Vì quá trình quét thiết bị truyền tin sử dụng BLE, nên có thể hoạt động ở chế độ nền. Sau đây là một số điều bạn cần lưu ý khi quyết định sử dụng chế độ nền:

  • BLE ở chế độ nền sẽ tốn thêm pin. Chi phí thấp, nhưng bạn nên đo lường chi phí này trước khi quyết định sử dụng chế độ nền.
  • iOS sẽ yêu cầu người dùng cấp quyền sử dụng thông tin vị trí ở chế độ nền nếu tính năng quét iBeacon được bật hoặc chế độ nguồn điện thấp bị tắt.

Để bật tính năng quét tín hiệu ở chế độ nền, hãy làm theo các bước bổ sung sau:

  • Bật chế độ nền cho gói thuê bao bằng cách truyền vào một đối tượng GNSBeaconStrategy được định cấu hình đúng cách. Đoạn mã sau đây minh hoạ cách thực hiện việc này:

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

  • Thêm các mục bắt buộc vào Info.plist của ứng dụng:

    • UIBackgroundModes mục:

      • bluetooth-central để quét BLE ở chế độ nền.
      • location để quét iBeacon ở chế độ nền bằng chế độ công suất cao. Bạn có thể bỏ qua bước này nếu chỉ quét các beacon Eddystone ở chế độ tiêu thụ ít năng lượng.
    • Chuỗi NSLocationAlwaysUsageDescription mô tả lý do bạn sẽ theo dõi vị trí của người dùng ở chế độ nền. Ví dụ: "Chúng tôi cần thông tin vị trí của bạn để quét các beacon ở chế độ nền". Hãy xem tài liệu của Apple để biết thông tin chi tiết. Bạn có thể bỏ qua bước này nếu chỉ quét các beacon Eddystone ở chế độ tiết kiệm pin.

  • Người dùng có thể bật hoặc tắt tính năng quét ở chế độ nền trong ứng dụng của bạn không? Nếu có, bạn nên lưu giá trị chế độ nền vào NSUserDefaults vì iOS có thể tắt ứng dụng của bạn bất cứ lúc nào khi ứng dụng ở chế độ nền. Ứng dụng của bạn phải làm những việc sau:

    • Lưu giá trị chế độ nền vào NSUserDefaults bất cứ khi nào người dùng thay đổi giá trị này.
    • Khi khởi động, hãy đọc thông tin này từ NSUserDefaults và khôi phục chế độ đăng ký beacon nếu chế độ nền được bật.

Thông báo ở chế độ nền

Nếu muốn ứng dụng thông báo cho người dùng khi phát hiện thấy các beacon ở chế độ nền, bạn có thể sử dụng thông báo cục bộ. Để biết thông tin chi tiết, hãy xem phần thông báo ở chế độ nền.