Xuất bản và đăng ký

Nearby Messages API là một API đăng ký xuất bản cho phép các thiết bị ở gần trao đổi tải dữ liệu nhỏ. Sau khi thiết bị đăng thông báo, các thiết bị ở gần có thể nhận được thông báo đó. Kích thước tin nhắn nên được giữ ở mức khá nhỏ để duy trì hiệu suất tốt. Dịch vụ này không dùng để trao đổi các đối tượng lớn hơn, chẳng hạn như ảnh và video.

Nhóm thiết bị ở gần được xác định bằng cách trao đổi các mã thông báo nhỏ qua Bluetooth và âm thanh gần như siêu âm (không nghe được). Khi phát hiện mã thông báo từ một thiết bị ở gần, thiết bị sẽ gửi mã thông báo này đến máy chủ Nearby Message (Thông báo lân cận) để xác thực mã và kiểm tra xem có thông báo nào cần gửi cho nhóm gói thuê bao hiện tại của ứng dụng hay không.

Một ứng dụng có thể kiểm soát nhóm phương tiện dùng để khám phá thiết bị, cũng như liệu các phương tiện đó có được dùng để phát đi mã thông báo và/hoặc quét tìm mã thông báo hay không. Theo mặc định, hoạt động phát sóng và quét sẽ được thực hiện trên tất cả các phương tiện. Để khám phá trên một tập hợp con hoặc phương tiện, cũng như kiểm soát việc phát đi thông báo hay quét, bạn phải truyền các tham số bổ sung khi tạo ấn bản và gói thuê bao.

Thư viện này chạy trên iOS 7 trở lên và được tạo bằng SDK iOS 8.

Tạo trình quản lý thông báo

Mã này sẽ tạo một đối tượng trình quản lý thông báo để bạn có thể phát hành và đăng ký. Hoạt động trao đổi thông báo chưa được xác thực, vì vậy, bạn phải cung cấp khoá API công khai cho iOS. Bạn có thể tạo một nhà phát triển bằng cách sử dụng mục nhập trong Google Developers Console cho dự án của bạn.

Objective-C

#import <GNSMessages.h>

GNSMessageManager *messageManager =
    [[GNSMessageManager alloc] initWithAPIKey:@"API_KEY"];

Swift

let messageManager = GNSMessageManager(APIKey: "API_KEY")

Đăng thông báo

Đoạn mã này minh hoạ việc xuất bản một thông báo có chứa tên. Ấn bản đó sẽ hoạt động chừng nào đối tượng ấn bản đó còn tồn tại. Để dừng phát hành, hãy giải phóng đối tượng ấn bản.

Objective-C

id<GNSPublication> publication =
    [messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]];

Swift

let publication =
    messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)))

Đăng ký tin nhắn

Đoạn mã này minh hoạ việc đăng ký nhận tất cả các tên mà đoạn mã ấn bản trước đó chia sẻ. Gói thuê bao sẽ hoạt động miễn là các đối tượng thuê bao còn tồn tại. Để ngừng đăng ký, hãy huỷ đối tượng thuê bao.

Trình xử lý tìm thấy thông báo được gọi khi phát hiện thấy các thiết bị ở gần đang phát hành thông báo. Trình xử lý bị mất thông báo được gọi khi không còn quan sát thấy một thông báo (thiết bị đã nằm ngoài phạm vi hoặc không còn đăng thông báo đó nữa).

Objective-C

id<GNSSubscription> subscription =
    [messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) {
      // Add the name to a list for display
    }
    messageLostHandler:^(GNSMessage *message) {
      // Remove the name from the list
    }];

Swift

let subscription =
    messageManager.subscription(messageFoundHandler: { (message: GNSMessage?) in
      // Add the name to a list for display
    },
    messageLostHandler: { (message: GNSMessage?) in
      // Remove the name from the list
    })

Phương tiện khám phá

Theo mặc định, cả hai phương tiện (âm thanh và Bluetooth) sẽ được dùng để khám phá các thiết bị ở gần, đồng thời cả hai phương tiện sẽ phát đi và quét. Đối với một số trường hợp nhất định, bạn bắt buộc phải thêm các mục sau vào Info.plist của ứng dụng:

  • Nếu ứng dụng của bạn quét bằng âm thanh, hãy thêm NSMicrophoneUsageDescription. Đây là chuỗi mô tả lý do bạn sử dụng micrô. Ví dụ: "Micrô nghe các mã thông báo ẩn danh từ các thiết bị ở gần".

  • Nếu ứng dụng của bạn truyền phát bằng BLE, hãy thêm NSBluetoothPeripheralUsageDescription. Đây là một chuỗi mô tả lý do bạn sẽ quảng cáo trên BLE. Ví dụ: "Quảng cáo mã ẩn danh qua Bluetooth để khám phá các thiết bị ở gần".

Trong một số trường hợp, ứng dụng của bạn có thể chỉ cần sử dụng một trong các phương tiện và có thể không cần thực hiện cả việc phát sóng và quét trên phương tiện đó.

Ví dụ: một ứng dụng được thiết kế để kết nối với hộp giải mã tín hiệu số đang phát âm thanh, chỉ cần quét âm thanh để tìm ra ứng dụng đó. Đoạn mã sau đây cho biết cách phát hành một thông báo lên hộp giải mã tín hiệu số đó bằng cách chỉ quét âm thanh để khám phá:

Objective-C

id<GNSPublication> publication = [messageManager publicationWithMessage:message
    paramsBlock:^(GNSPublicationParams *params) {
      params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
        params.discoveryMediums = kGNSDiscoveryMediumsAudio;
        params.discoveryMode = kGNSDiscoveryModeScan;
      }];
    }];

Swift

let publication = messageManager.publication(with: message,
    paramsBlock: { (params: GNSPublicationParams?) in
      guard let params = params else { return }
      params.strategy = GNSStrategy(paramsBlock: { (params: GNSStrategyParams?) in
        guard let params = params else { return }
        params.discoveryMediums = .audio
        params.discoveryMode = .scan
      })
    })

Bật tính năng ghi nhật ký gỡ lỗi

Tính năng ghi nhật ký gỡ lỗi sẽ in các sự kiện nội bộ quan trọng vào bảng điều khiển có thể hữu ích trong việc theo dõi các sự cố mà bạn có thể gặp phải khi tích hợp Thông báo lân cận vào ứng dụng của mình. Chúng tôi sẽ yêu cầu các nhật ký này nếu bạn liên hệ với chúng tôi để được hỗ trợ kỹ thuật.

Bạn nên bật chế độ này trước khi tạo trình quản lý thông báo. Đoạn mã này cho biết cách bật tính năng ghi nhật ký gỡ lỗi:

Objective-C

[GNSMessageManager setDebugLoggingEnabled:YES];

Swift

GNSMessageManager.setDebugLoggingEnabled(true)

Theo dõi trạng thái của quyền sử dụng tính năng Chia sẻ lân cận

Cần có sự đồng ý của người dùng để bật tính năng khám phá thiết bị. Trạng thái này được biểu thị bằng trạng thái quyền sử dụng tính năng Chia sẻ lân cận. Trong lệnh gọi đầu tiên để tạo một ấn bản hoặc gói thuê bao, người dùng sẽ thấy một hộp thoại đồng ý. Nếu người dùng không đồng ý, tính năng khám phá thiết bị sẽ không hoạt động. Trong trường hợp này, ứng dụng của bạn sẽ hiển thị một thông báo để nhắc người dùng rằng tính năng khám phá thiết bị đã bị tắt. Trạng thái của quyền được lưu trữ trong NSUserDefaults.

Đoạn mã sau đây minh hoạ việc đăng ký trạng thái cấp quyền. Trình xử lý đã thay đổi trạng thái quyền được gọi mỗi khi trạng thái thay đổi và sẽ không được gọi lần đầu tiên cho đến khi người dùng cấp hoặc từ chối cấp quyền. Thả đối tượng quyền để ngừng đăng ký.

Objective-C

GNSPermission *nearbyPermission = [[GNSPermission alloc] initWithChangedHandler:^(BOOL granted) {
  // Update the UI here
}];

Swift

let nearbyPermission = GNSPermission(changedHandler: { (granted: Bool) in
  // Update the UI here
})

Ứng dụng của bạn có thể cung cấp cho người dùng cách thay đổi trạng thái quyền; ví dụ: bằng cách sử dụng nút bật/tắt trên trang cài đặt.

Dưới đây là ví dụ về cách nhận và thiết lập trạng thái cho quyền.

Objective-C

BOOL permissionState = [GNSPermission isGranted];
[GNSPermission setGranted:!permissionState];  // toggle the state

Swift

let permissionState = GNSPermission.isGranted()
GNSPermission.setGranted(!permissionState)  // toggle the state

Chế độ cài đặt theo dõi của người dùng ảnh hưởng đến tính năng Lân cận

Nếu người dùng từ chối cấp quyền sử dụng micrô, từ chối cấp quyền truy cập vào Bluetooth hoặc tắt Bluetooth, thì tính năng Lân cận cũng sẽ không hoạt động hoặc có thể không hoạt động. Trong những trường hợp như vậy, ứng dụng sẽ hiển thị một thông báo để cảnh báo người dùng rằng các hoạt động của tính năng Lân cận đang bị cản trở. Đoạn mã sau cho biết cách theo dõi trạng thái các chế độ cài đặt của người dùng bằng cách truyền các trình xử lý khi tạo trình quản lý thông báo:

Objective-C

GNSMessageManager *messageManager = [[GNSMessageManager alloc]
    initWithAPIKey:API_KEY
       paramsBlock:^(GNSMessageManagerParams *params) {
         params.microphonePermissionErrorHandler = ^(BOOL hasError) {
           // Update the UI for microphone permission
         };
         params.bluetoothPowerErrorHandler = ^(BOOL hasError) {
           // Update the UI for Bluetooth power
         };
         params.bluetoothPermissionErrorHandler = ^(BOOL hasError) {
           // Update the UI for Bluetooth permission
         };
}];

Swift

let messageManager = GNSMessageManager(
         APIKey: API_KEY,
    paramsBlock: { (params: GNSMessageManagerParams?) in
      guard let params = params else { return }
      params.microphonePermissionErrorHandler = { (hasError: Bool) in
        // Update the UI for microphone permission
      }
      params.bluetoothPowerErrorHandler = { (hasError: Bool) in
        // Update the UI for Bluetooth power
      }
      params.bluetoothPermissionErrorHandler = { (hasError: Bool) in
        // Update the UI for Bluetooth permission
      }
    })

Ghi đè hộp thoại quyền sử dụng tính năng Lân cận

Tuỳ thuộc vào các tham số bạn truyền vào ấn bản và gói thuê bao, iOS có thể yêu cầu nhiều quyền trước khi cho phép tính năng Lân cận hoạt động. Ví dụ: chiến lược mặc định theo dõi dữ liệu được truyền qua âm thanh gần như siêu âm, vì vậy, iOS sẽ yêu cầu quyền sử dụng micrô. Trong những trường hợp như vậy, tính năng Lân cận sẽ hiển thị hộp thoại "kiểm tra" để giải thích lý do người dùng được yêu cầu cấp quyền.

Nếu bạn muốn cung cấp hộp thoại "kiểm thử" tuỳ chỉnh, hãy đặt tham số permissionRequestHandler thành một khối tuỳ chỉnh trong thông số ấn bản hoặc thông số gói thuê bao. Khối tuỳ chỉnh của bạn phải gọi khối permissionHandler sau khi người dùng đã phản hồi. Đoạn mã sau đây cho biết cách thực hiện việc này cho một ấn bản:

Objective-C

id<GNSPublication> publication =
    [messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]
                               paramsBlock:^(GNSPublicationParams *params) {
                                 params.permissionRequestHandler = ^(GNSPermissionHandler permissionHandler) {
                                   // Show your custom dialog here.
                                   // Don't forget to call permissionHandler() with YES or NO when the user dismisses it.
                                 };
                               }];

Swift

let publication =
    messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)),
        paramsBlock: { (params: GNSPublicationParams?) in
          guard let params = params else { return }
          params.permissionRequestHandler = { (permissionHandler: GNSPermissionHandler?) in
            // Show your custom dialog here.
            // Don't forget to call permissionHandler() with true or false when the user dismisses it.
          }
        })

Hoạt động ở chế độ nền

Các ấn bản và gói thuê bao dùng BLE để khám phá thiết bị 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:

  • Hoạt động trong nền chỉ được sử dụng phương tiện BLE; không hỗ trợ âm thanh.
  • 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 quảng cáo qua BLE trong nền.

Để thêm chế độ nền vào một ấn bản hoặc gói thuê bao, hãy làm theo các bước bổ sung sau:

  • Bật chế độ nền và chỉ BLE trong ấn bản hoặc gói thuê bao bằng cách truyền vào một đối tượng GNSStrategy đượ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 đối với một gói thuê bao:

    Objective-C

    id<GNSSubscription> subscription =
        [messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) {
          // Add the name to a list for display
        }
        messageLostHandler:^(GNSMessage *message) {
          // Remove the name from the list
        }
        paramsBlock:^(GNSSubscriptionParams *params) {
          params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
            params.allowInBackground = YES;
            params.discoveryMediums = kGNSDiscoveryMediumsBLE;
          }];
        }];
    

    Swift

    let subscription =
        messageManager.subscription(messageFoundHandler: { (message: GNSMessage?) in
          // Add the name to a list for display
        },
        messageLostHandler: { (message: GNSMessage?) in
          // Remove the name from the list
        },
        paramsBlock:{ (params: GNSSubscriptionParams?) in
          guard let params = params else { return }
          params.strategy = GNSStrategy(paramsBlock: { (params: GNSStrategyParams?) in
            guard let params = params else { return }
            params.allowInBackground = true
            params.discoveryMediums = .BLE
          })
        })
    

  • Thêm các mục nhập này vào Info.plist của ứng dụng:

    • UIBackgroundModes mục nhập:

      • bluetooth-central để quét BLE trong nền. Chỉ cần thiết khi chế độ khám phá có bao gồm tính năng quét theo mặc định.
      • bluetooth-peripheral cho quảng cáo BLE trong nền. Chỉ cần thiết khi chế độ khám phá có bao gồm tính năng phát sóng theo mặc định.
    • Chuỗi NSBluetoothPeripheralUsageDescription mô tả lý do bạn quảng cáo trên BLE. Ví dụ: "Mã thông báo ẩn danh được quảng cáo qua Bluetooth để khám phá các thiết bị ở gần". Vui lòng xem tài liệu của Apple để biết thông tin chi tiết.

  • Hệ thống có thể tắt ứng dụng của bạn bất cứ lúc nào trong khi chạy ở chế độ nền. Nếu chế độ nền là một chế độ cài đặt mà người dùng có thể bật hoặc tắt, thì ứng dụng của bạn cần làm như 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 thông báo này từ NSUserDefaults rồi khôi phục các ấn bản và/hoặc gói thuê bao lân cận 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 gói thuê bao nhận được tin nhắn trong khi ở chế độ nền, bạn có thể sử dụng thông báo cục bộ.

Hãy làm theo các bước sau để thêm chúng vào ứng dụng của bạn:

  • Đăng ký nhận thông báo cục bộ khi khởi động:

    Objective-C

    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
      [[UIApplication sharedApplication] registerUserNotificationSettings:
          [UIUserNotificationSettings settingsForTypes:
              UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound
                                            categories:nil]];
    }
    

    Swift

    UIApplication.shared.registerUserNotificationSettings(
        UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil))
    

  • Gửi thông báo cục bộ trong trình xử lý tìm thấy tin nhắn của gói thuê bao:

    Objective-C

    GNSMessageHandler myMessageFoundHandler = ^(GNSMessage *message) {
        // Send a local notification if not in the foreground.
        if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
          UILocalNotification *localNotification = [[UILocalNotification alloc] init];
          localNotification.alertBody = @"Message received";
          [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
        }
        // Process the new message...
      };
    

    Swift

    let myMessageFoundHandler: GNSMessageHandler = { (message: GNSMessage?) in
      // Send a local notification if not in the foreground.
      if UIApplication.shared.applicationState != .active {
        let localNotification = UILocalNotification()
        localNotification.alertBody = "Message received"
        UIApplication.shared.presentLocalNotificationNow(localNotification)
      }
      // Process the new message...
    }