Nearby Messages API là một API xuất bản-đăng ký cho phép các thiết bị lân cận trao đổi các tải trọng dữ liệu nhỏ. Sau khi một thiết bị xuất bản một thông báo, các thiết bị lân cận có thể nhận được thông báo đó. Bạn nên giữ kích thước thông báo ở 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.
Tập hợp các 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 siêu âm (không nghe thấy). Khi một thiết bị phát hiện thấy 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 máy chủ Nearby Messages để xác thực và kiểm tra xem có thông báo nào cần gửi cho nhóm đăng ký hiện tại của ứng dụng hay không.
Một ứng dụng có thể kiểm soát tập hợp các phương tiện được dùng để phát hiện thiết bị, cũng như việc các phương tiện đó có được dùng để truyền mã thông báo và/hoặc quét mã thông báo hay không. Theo mặc định, hoạt động phát và quét đượ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 và để kiểm soát việc phát sóng hay quét, bạn phải truyền các tham số bổ sung khi tạo các ấn phẩm và đăng ký.
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 một trình quản lý thông báo
Đoạn mã này tạo một đối tượng trình quản lý thông báo, cho phép bạn xuất bản và đăng ký. Hoạt động trao đổi thông báo không đượ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 dự án bằng mục Google Developers Console cho dự án của mình.
Objective-C
#import <GNSMessages.h>
GNSMessageManager *messageManager =
[[GNSMessageManager alloc] initWithAPIKey:@"API_KEY"];
Swift
let messageManager = GNSMessageManager(APIKey: "API_KEY")
Xuất bản 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 phẩm sẽ hoạt động miễn là đối tượng ấn phẩm tồn tại. Để ngừng xuất bản, hãy giải phóng đối tượng xuất 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ý nhận tin nhắn
Đoạn mã này minh hoạ cách đăng ký tất cả tên do đoạn mã xuất bản trước đó chia sẻ. Gói thuê bao sẽ hoạt động miễn là đối tượng thuê bao tồn tại. Để ngừng đăng ký, hãy giải phóng đối tượng đăng ký.
Trình xử lý tìm thấy thông báo sẽ được gọi khi phát hiện thấy các thiết bị lân cận đang xuất bản thông báo. Trình xử lý thông báo bị mất sẽ được gọi khi một thông báo không còn được quan sát nữa (thiết bị đã ra khỏi phạm vi hoặc không còn xuất bản 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 và quét. Trong một số trường hợp, bạn 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à một chuỗi mô tả lý do bạn sẽ sử dụng micrô. Ví dụ: "Micrô sẽ 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 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ụ: "Một mã thông báo ẩn danh được quảng cáo 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à không cần thực hiện cả hoạt động 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 truyền hình đang phát sóng chỉ cần quét âm thanh để phát hiện hộp đó. Đoạn mã sau đây cho biết cách xuất bản một thông báo đến hộp giải mã tín hiệu truyền hình đó chỉ bằng cách quét âm thanh để phát hiện:
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
Gỡ lỗi nhật ký in các sự kiện nội bộ quan trọng vào bảng điều khiển. Điều này có thể hữu ích cho việc theo dõi các vấn đề mà bạn có thể gặp phải khi tích hợp Nearby Messages vào ứng dụng của mình. Chúng tôi sẽ yêu cầu bạn cung cấp những 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 tính năng này trước khi tạo một 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 quyền đối với Thiết bị ở gần
Bạn phải có sự đồng ý của người dùng để bật tính năng phát hiện thiết bị. Điều này được biểu thị bằng trạng thái quyền cho Dịch vụ lân cận. Trong lần gọi đầu tiên để tạo một ấn phẩm 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 phát hiện 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 một thông báo để nhắc người dùng rằng tính năng phát hiện thiết bị đang bị tắt. Trạng thái quyền được lưu trữ trong NSUserDefaults
.
Đoạn mã sau đây minh hoạ cách đăng ký theo dõi trạng thái quyền. Trình xử lý thay đổi trạng thái quyền được gọi bất cứ khi nào trạng thái thay đổi và không được gọi vào lần đầu tiên cho đến khi người dùng cấp hoặc từ chối quyền. Giải phóng đối tượng quyền để dừ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 của quyền; ví dụ: bằng cách sử dụng công tắc bật/tắt trên trang cài đặt.
Sau đây là ví dụ về cách lấy và đặt trạng thái 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
Theo dõi chế độ cài đặt 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 truy cập micrô, từ chối cấp quyền truy cập Bluetooth hoặc đã tắt Bluetooth, thì tính năng Lân cận sẽ không hoạt động hiệu quả hoặc có thể hoàn toàn không hoạt động. Trong những trường hợp này, ứng dụng của bạn phải 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 Nearby đang bị cản trở. Đoạn mã sau đây cho biết cách theo dõi trạng thái của các chế độ cài đặt người dùng này bằng cách truyền 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 truy cập vào thiết bị ở gần
Tuỳ thuộc vào các tham số mà bạn truyền vào các thông báo và dịch vụ đăng ký, iOS có thể yêu cầu nhiều quyền trước khi cho phép Nearby hoạt động. Ví dụ: chiến lược mặc định sẽ lắng nghe dữ liệu được truyền qua âm thanh gần siêu âm, vì vậy iOS sẽ yêu cầu cấp quyền sử dụng micrô. Trong những trường hợp này, Nearby sẽ hiện một hộp thoại "kiểm tra trước khi bay" 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 một hộp thoại "kiểm tra trước" tuỳ chỉnh, hãy đặt tham số permissionRequestHandler
thành một khối tuỳ chỉnh trong các tham số xuất bản hoặc đăng ký. Khối tuỳ chỉnh của bạn phải gọi khối permissionHandler
sau khi người dùng đã trả lời. Đoạn mã sau đây cho biết cách thực hiện việc này đối với một ấn phẩm:
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.
}
})
Thao tác trong nền
Các ứng dụng xuất bản và đăng ký sử dụng BLE để phát hiện thiết bị 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:
- Các thao tác trong nền chỉ được sử dụng phương tiện BLE; không hỗ trợ âm thanh.
- 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 quảng cáo qua BLE ở chế độ nền.
Để thêm chế độ nền vào một ấn phẩm 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 phẩm hoặc gói thuê bao của bạn 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 này vào
Info.plist
của ứng dụng:UIBackgroundModes
mục:bluetooth-central
để quét BLE ở chế độ nền. Chỉ cần thiết khi chế độ khám phá bao gồm quét; chế độ này sẽ quét theo mặc định.bluetooth-peripheral
để quảng cáo BLE ở chế độ nền. Chỉ cần thiết khi chế độ phát hiện bao gồm việc phát sóng; chế độ này được bật theo mặc định.
NSBluetoothPeripheralUsageDescription
chuỗi mô tả lý do bạn sẽ quảng cáo trên BLE. Ví dụ: "Một mã thông báo ẩn danh được quảng cáo qua Bluetooth để khám phá các thiết bị ở gần." Hãy xem tài liệu của Apple để biết thông tin chi tiết.
Ứng dụng của bạn có thể bị hệ thống loại bỏ bất cứ lúc nào khi ở 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 phải làm như 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 dữ liệu này từ
NSUserDefaults
và khôi phục các ấn phẩm và/hoặc lượt đăng ký Lân cận nếu bạn bật chế độ nền.
- Lưu giá trị chế độ nền vào
Thông báo ở chế độ nền
Nếu muốn ứng dụng thông báo cho người dùng khi một gói thuê bao nhận được thông báo trong khi chạy ở 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 các thành phần này vào ứng dụng:
Đă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ý message-found 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... }