Настройка iOS приложения#
Настройка приложения для получения и отображения push-уведомлений#
Для получения и отображения push-уведомлений выполните следующие шаги:
Зарегистрируйте приложение в Apple Push Notification Service (APNs): Registering Your App with APNs.
Запросите разрешение на показ уведомлений: Asking Permission to Use Notifications.
Реализуйте метод
userNotificationCenter(_:willPresent:withCompletionHandler:)для отображения уведомлений, когда приложение запущено и активно: Handling Notifications and Notification-Related Actions.Реализуйте отправку токена на мобильный бекенд при вызове метода application(_:didRegisterForRemoteNotificationsWithDeviceToken:).
Пример AppDelegate после выполнения вышеуказанных действий#
@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert]) { (granted, error) in
if let error = error {
print("Failed to request notification center authorization: \\(error)")
}
}
application.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let stringToken = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
self.sendDeviceTokenToBackend(token: stringToken)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register for remote notifications: \\(error)")
// Try again later.
}
// MARK: - UNUserNotificationCenterDelegate
// The method will be called on the delegate only if the application is in the foreground.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound, .badge])
}
}
Отслеживание статусов доставки#
При получении уведомления вам необходимо передавать на наш сервер информацию об идентификаторе сообщения на нашей платформе и статусе уведомления. Для этого необходимо выполните следующие шаги:
Добавьте к приложению расширение Notification Service Extension.
В методе
didReceive(_:withContentHandler:)расширения отправляйте следующий HTTP-запрос:
POST <https://nativepush.i-dgtl.ru/notification-state>
Content-Type: application/json
{
"messageId": "MESSAGE_ID",
"state": "RECEIVED"
}
В ответ наш сервер должен вернуть 204 No Content.
Как добавить расширение Notification Service Extension?#
В Xcode выберите File → New → Target.
Выберите из списка шаблонов Notification Service Extension и нажмите Next.

Введите название расширения и нажмите Finish.
.png)
Пример реализации расширения#
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
if let messageId = bestAttemptContent.userInfo["messageId"] as? String {
sendReceivedStateCallback(messageId: messageId) { error in
if let error = error {
// handle request error
}
contentHandler(bestAttemptContent)
}
} else {
contentHandler(bestAttemptContent)
}
}
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
func sendReceivedStateCallback(messageId: String, completionHandler: @escaping (Error?) -> Void) {
#if DEBUG
let callbackUrl = "<https://nativepush-test.i-dgtl.ru/notification-state>"
#else
let callbackUrl = "<https://nativepush.i-dgtl.ru/notification-state>"
#endif
let callbackParams = ["messageId": messageId, "state": "RECEIVED"]
var request = URLRequest(url: URL(string: callbackUrl)!, timeoutInterval: 15)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: callbackParams)
let task = URLSession.shared.dataTask(with: request, completionHandler: { _, response, error in
guard error == nil else {
completionHandler(error)
return
}
if let httpResponse = response as? HTTPURLResponse {
guard (200...299).contains(httpResponse.statusCode) else {
completionHandler(NSError(domain: "unsuccessful http status code", code: httpResponse.statusCode, userInfo: nil))
return
}
}
completionHandler(nil)
})
task.resume()
}
}
{% hint style=»info» %}
Время выполнения метода didReceive(_:withContentHandler:) ограничено 30 секундами, однако мы рекомендуем устанавливать меньший таймаут запроса, так как уведомление пользователю будет показано только после вызова contentHandler.
{% endhint %}
Отправка уведомлений#
При отправке уведомлений используется ключ в формате.p8 для авторизации на сервере APNs, который вам нужно передать i-Digital.
Как создать ключ p8?#
Войдите в ваш Appple Developer Account и перейдите на страницу Certificates, Identifiers & Profiles.
В меню слева выберите Keys и нажмите на синюю кнопку (+).

Введите название ключа, отметьте Apple Push Notifications service (APNs) и нажмите Continue.

Нажмите Register, после чего скачайте созданный ключ, нажав Download.
Как передать созданный p8 ключ в i-Digital?#
Отправьте письмо на support@i-dgtl.ru с темой «Подключение PUSH i-digital direct», указав в теле письма следующее:
название вашей организации,
файл ключа,
Key ID - отображается после создания ключа,
Team ID - можно найти в Appple Developer Account на странице Membership .