Nearby Messages API là một API xuất bản-đăng ký cho phép các thiết bị ở gần trao đổi các tải trọng dữ liệu nhỏ. Sau khi thiết bị đăng thông báo, ở gần thiết bị nào khác đều có thể nhận tin nhắn. Kích thước thư nên được giữ khá nhỏ để duy trì hiệu suất tốt. Dịch vụ này không dành cho việc trao đổi các tệp có dung lượng lớn 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 như siêu âm (không nghe được). Khi thiết bị phát hiện thấy mã thông báo từ một thiết bị lân cận, thiết bị này sẽ gửi mã thông báo này đế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 gói thuê bao hiện tại.
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ị, và liệu phương tiện được dùng để truyền mã thông báo và/hoặc quét tìm mã thông báo hay không. Theo mặc định, việc phát sóng và quét được thực hiện trên tất cả các phương tiện. Việc cần làm phát hiện trên một tập hợp con hoặc phương tiện cũng như để kiểm soát xem nên phát hay quét, bạn phải truyền các thông 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 xây dựng bằng SDK iOS 8.
Tạo trình quản lý tin nhắ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ý. Trao đổi tin nhắn chưa được xác thực, vì vậy bạn phải cung cấp khoá API công khai dành cho iOS. Bạn có thể tạo một tài khoản bằng cách sử dụng mục nhập 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ạ cách đăng một thông báo có chứa tên. Ấn bản này vẫn hoạt động chừng nào đối tượng ấn bản đó còn tồn tại. Để dừng xuất bản, phát hành đố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ý nhận tin nhắn
Đoạn mã này minh hoạ việc đăng ký tất cả các tên được chia sẻ bởi đoạn trích ấn bản trước. Gói thuê bao này còn hiệu lực miễn là đã tồn tại. Để ngừng đăng ký, hãy huỷ đăng ký .
Trình xử lý đã tìm thấy tin nhắn sẽ được gọi khi các thiết bị ở gần đang xuất bản tin nhắn được phát hiện. Trình xử lý tin nhắn bị mất được gọi khi có tin nhắn không (thiết bị đã nằm ngoài phạm vi hoặc không còn xuất bản ).
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 để phát hiện các thiết bị ở gần
thiết bị và cả hai phương tiện sẽ truyền phát và quét. Đối với một số trường hợp nhất định, bạn
cầ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
, mô tả lý do bạn sẽ sử dụng micrô. Ví dụ: "The micrô sẽ theo dõi 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 tin bằng BLE, hãy thêm
NSBluetoothPeripheralUsageDescription
, là một chuỗi mô tả lý do bạn sẽ 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".
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 hai phương tiện đó và có thể không cần vừa phát sóng vừa 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ố phát sóng âm thanh chỉ cần quét âm thanh để khám phá âm thanh. Nội dung sau đây đoạn mã 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ố mà chỉ dùng âm thanh quét để 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
Thao tác gỡ lỗi ghi nhật ký sẽ in các sự kiện nội bộ quan trọng ra 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 tính năng Lân cận Tin nhắn vào ứng dụng của bạn. Chúng tôi sẽ yêu cầu cung cấp các nhật ký này nếu bạn liên hệ với chúng tôi về hỗ trợ kỹ thuật.
Bạn nên bật chế độ này trước khi tạo trình quản lý tin nhắn. Đoạn mã này cho thấy 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 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ị. Điều này được biểu thị bằng
Trạng thái cấp quyền ở gần. Trong cuộc gọi đầu tiên để tạo ấn bản hoặc
thì người dùng sẽ thấy một hộp thoại đồng ý. Nếu người dùng không
đồng ý, thì 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ị
để nhắc người dùng rằng tính năng khám phá thiết bị đã bị tắt. Quyền
trạng thái được lưu trữ trong NSUserDefaults
.
Đoạn mã sau minh hoạ việc đăng ký trạng thái cấp quyền. Chiến lược phát hành đĩa đơn Trình xử lý trạng thái cấp quyền đã thay đổi sẽ được gọi mỗi khi trạng thái thay đổi và trình xử lý không được gọi 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 để 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ể cho phép người dùng thay đổi trạng thái quyền; với ví dụ: bằng cách sử dụng nút bật/tắt trên trang cài đặt.
Sau đây là ví dụ về cách tải và đặt trạng thái cấp 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 các tùy chọn cài đặt của người dùng có ả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, 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. Ứng dụng của bạn phải hiển thị một thông báo trong những trường hợp này, cảnh báo người dùng rằng ứng dụng hoạt động 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 cài đặt người dùng này bằng cách truyền các trình xử lý khi tạo thông báo người quản lý:
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 cấp quyền Lân cận
Tuỳ thuộc vào các thông số bạn chuyển vào ấn bản và gói thuê bao, iOS có thể yêu cầu nhiều quyền khác nhau trước khi cho phép tính năng Lân cận hoạt động. Cho chẳng hạn như, chiến lược mặc định theo dõi dữ liệu được truyền qua sóng gần siêu âm nên iOS sẽ yêu cầu quyền sử dụng micrô. Trong những trường hợp này, Tính năng lân cận sẽ hiển thị một "preflight" hộp thoại giải thích lý do yêu cầu người dùng để cấp quyền.
Nếu bạn muốn cung cấp tính năng "kiểm tra" tuỳ chỉnh hãy đặt
permissionRequestHandler
thành một khối tuỳ chỉnh trong ấn bản hoặc
thông số gói thuê bao. Khối tuỳ chỉnh phải gọi permissionHandler
chặn 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
đối với 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 sử dụng BLE để khám phá thiết bị có thể hoạt động trong nền. Sau đâ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 ở chế độ nền chỉ được sử dụng môi trường BLE; không hỗ trợ âm thanh.
- Sẽ tốn thêm chi phí pin cho BLE ở chế độ nền. Chi phí thấp, nhưng bạn nên đo lường độ chính xác 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 ấn bản hoặc gói thuê bao, hãy làm theo các bước bổ sung sau các bước:
Bật chế độ nền và chỉ BLE trong ấn bản hoặc gói thuê bao của bạn muộn nhất vào truyền vào đối tượng
GNSStrategy
được định cấu hình đúng cách. Đoạn mã sau hướng dẫn 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 sau vào
Info.plist
của ứng dụng:UIBackgroundModes
mục nhập:bluetooth-central
để quét BLE ở chế độ nền. Chỉ cần thiết khi chế độ khám phá bao gồm cả quét; theo mặc định.bluetooth-peripheral
để quảng cáo BLE trong nền. Cần thiết chỉ khi chế độ khám phá bao gồm cả phát sóng; theo mặc định.
Chuỗi
NSBluetoothPeripheralUsageDescription
mô tả lý do bạn sẽ quảng cáo trên BLE. Ví dụ: "Mã thông báo ẩn danh là quảng cáo qua Bluetooth để khám phá các thiết bị lân cận". 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 khi ở chế độ nền. Nếu chế độ nền là một cài đặt mà người dùng có thể bật hoặc tắt ứng dụng của bạn sẽ thực hiện những việc sau:
- Lưu giá trị của chế độ nền vào
NSUserDefaults
bất cứ khi nào người dùng thay đổi cuộc trò chuyện đó. - Khi khởi động, đọc từ
NSUserDefaults
và khôi phục ứng dụng Lân cận ấn bản và/hoặc gói thuê bao nếu bật chế độ nền.
- Lưu giá trị của chế độ nền vào
Thông báo trong nền
Nếu bạn 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 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ý tin nhắn đã tìm thấy 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... }