И это то, что мне кажется несовместимым в Apple Notification Framework
алкиваемся с непонятной проблемой при использовании push-уведомлений Apple через APN. У нас есть следующий сценарий (вполне стандартный, я думаю):
Когда наше приложение, давайте назовем его «MyApp» здесь, устанавливается и запускается в первый раз, мы запрашиваем у пользователя разрешения на отправку ему Push-уведомлений через «MyApp».
В этом примере AppDelegate выглядит так:
import UIKit
import UserNotifications
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Register Remote Notifications
UNUserNotificationCenter.current().delegate = self
self.registerForPushNotifications()
return true
}
// MARK: - Remote Notifications
func registerForPushNotifications() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
guard granted else {
return
}
self.getNotificationSettings()
}
}
func getNotificationSettings() {
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
guard settings.authorizationStatus == .authorized else {
return
}
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { (data) -> String in
return String(format: "%02.2hhx", data)
}
let token = tokenParts.joined()
print("ApnToken: \(token)")
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("did Fail to Register for RemoteNotifications")
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("willPresentNotification!")
completionHandler([.badge, .sound, .alert])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("UserDidResponseToNotification!")
completionHandler()
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("DidReceiveRemoteNotification!")
completionHandler(.newData)
}
}
Таким образом, пользователь устанавливает и запускает приложение, и его спрашивают, разрешено ли «MyApp» отправлять пользователю Push-уведомления. Если пользователь принимает Push-уведомленияapplication(_:didRegisterForRemoteNotificationsWithDeviceToken:)
и передаем полученный deviceToken нашему API.
Теперь часть, которая смущает меня:
У пользователя также есть возможность отключить Push-уведомления позже через iPhone-настройки, например, так: «Настройки»> «MyApp»> «Уведомления»> «Разрешить уведомления»> «Отключение».
Наш API теперь имеет deviceToken for APN, но пользователь отключил Push-уведомления через iPhone-Settings.
Проблема":
После того, как пользователь отключил Push-уведомления, мы по-прежнему можем отправлять на устройство беззвучные Push-уведомления, и «MyApp» безошибочно возвращает данные.
Но в другом сценарии: Пользователь устанавливает и запускает «MyApp» и отказывается при первом запуске Push-уведомлений, получить устройство от Apple невозможно. Я пытался получить deviceToken от Apple, даже если пользователь отклонил оповещение о push-уведомлении следующим образом: (Но это не сработает - думаю, Apple не предоставит мое сообщение, если пользователь отказывается)
func registerForPushNotifications() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
self.getNotificationSettings()
}
}
func getNotificationSettings() {
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { (data) -> String in
return String(format: "%02.2hhx", data)
}
let token = tokenParts.joined()
print("ApnToken: \(token)")
}
Кажется, что не имеет значения, что пользователь делает, если он принимает Push-уведомления при первом запуске. Я имею в виду хорошо, мы не можем показать информацию через баннер или что-то еще пользователю, но мы можем передавать данные на устройство с помощью APN, даже если пользователь отключил эту настройку позже. (Но мы не можем отправить что-либо, если он отказывается при запуске приложения - нам нужно устройство, взятое один раз)
Я что-то здесь неправильно понимаю? Это кажется противоречивым для меня.
Я попытался уточнить свой вопрос, чтобы каждый мог понять, что я прошу. Извините за мой "плохой" английский язык, так как не являющийся носителем языка задавать здесь конкретные вопросы с большим контекстом. В любом случае, если вам нужна дополнительная информация или вы не поняли один или несколько пунктов из того, что я спрашиваю, дайте мне знать, я предоставлю подробную информацию и уточню свой вопрос.
Я не знаю, имеет ли это значение, но в данный момент мы используем APN-Development-Certificate (еще не сертификат распространения)