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

Ứng dụng của bạn có thể đăng ký thông báo báo hiệu Bluetooth năng lượng thấp (BLE) bằng cách sử dụng cùng một cơ chế dùng để đăng ký các thông báo do các thiết bị lân cận khác phát hành.

Theo mặc định, gói thuê bao beacon chỉ hoạt động khi ứng dụng của bạn chạy ở nền trước. Khi ứng dụng của bạn chuyển sang chạy ở chế độ nền, các gói thuê bao sẽ tự động ngừng quét tìm beacon. Vui lòng xem bài viết Quét nền để biết thông tin chi tiết về cách bật tính năng quét nền.

Để đăng ký beacon, hãy đặt tham số deviceTypesToDiscover thành kGNSDeviceBLEBeacon trong thông số gói thuê bao. Đ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
    })

Gói thuê bao ở trên chỉ phát hiện các beacon thuộc dự án của bạn và nhận tất cả thông báo từ các beacon đó. Nếu muốn nhận thông báo từ các beacon được đăng ký bằng một không gian tên khác, bạn có thể chuyển một không gian tên vào các thông số gói thuê bao. 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, gói thuê bao beacon sẽ quét cho cả hai loại beacon, Eddystone và iBeacon. Khi tính năng quét iBeacon được bật, 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 bao gồm khoá NSLocationWhenInUseUsageDescription cùng với nội dung giải thích ngắn gọn về lý do ứng dụng sử dụng thông tin vị trí. Vui lòng 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 thông tin 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 khi tiết kiệm pin sẽ được bật, đôi khi có thể dẫn đến độ trễ lớn khi tìm thấy các beacon Eddystone. Khi bạn tắt chế độ tiết kiệm pin, tính năng quét iBeacon sẽ giúp tìm các beacon Eddystone, qua đó có thể giảm các độ trễ này. Tuy nhiên, điều này dẫn đến mức sử dụng pin nhiều hơn và iOS sẽ yêu cầu người dùng cấp quyền sử dụng thông tin vị trí.

Đoạn mã sau đây cho biết cách tắt chế độ tiết kiệm pin khi quét tìm 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 tìm iBeacons, 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 quyền Lân cận. Nếu bạn muốn ghi đè hộp thoại này (ví dụ: để cung cấp hộp thoại "kiểm thử" giải thích lý do cần có quyền truy cập thông tin vị trí), hãy đặt permissionRequestHandler thành một khối tuỳ chỉnh trong thông số gói thuê bao. Đ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 nền

Vì tính năng quét beacon sử dụng BLE nên tính năng này có thể hoạt động ở chế độ nền. Dưới đây là một số điều bạn nên lưu ý khi quyết định sử dụng chế độ nền:

  • Tính năng BLE ở chế độ nền sẽ tốn thêm pin. Chi phí thấp, nhưng bạn nên đo lường 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 đang bật hoặc chế độ tiết kiệm pin bị tắt.

Để bật tính năng quét beacon trong 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 một đối tượng GNSBeaconStrategy được định cấu hình đúng cách. Đ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.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 nhập:

      • bluetooth-central để quét BLE trong nền.
      • location để quét iBeacon ở chế độ nền ở chế độ tiết kiệm pin. Bạn có thể bỏ qua thuộc tính này nếu chỉ quét công suất thấp cho các beacon Eddystone.
    • 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ụ: "Bạn cần quét vị trí của mình để tìm beacon trong nền". Vui lòng xem tài liệu của Apple để biết thông tin chi tiết. Bạn có thể bỏ qua thuộc tính này nếu chỉ quét công suất thấp cho các beacon Eddystone.

  • Người dùng có thể bật hoặc tắt tính năng quét 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 đang chạy trong nền. Ứng dụng của bạn nên làm những việc sau:

    • Lưu giá trị chế độ nền vào NSUserDefaults mỗi khi người dùng thay đổi.
    • Khi khởi động, hãy đọc bản ghi này từ NSUserDefaults và khôi phục gói thuê bao beacon nếu chế độ nền đang bật.

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

Nếu muốn ứng dụng của mình thông báo cho người dùng khi phát hiện beacon trong 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 bài viết thông báo trong nền.