Инструкция по подключению мобильных пуш-уведомлений (iOS)
1. Подключение библиотеки
Данная библиотека распространяется с помощью Cocoapods. Для ее использования в Podfile необходимо добавить зависимость:
«pod "enkodpushlibrary"»
enkod позволяет использовать для отправки пуш-уведомлений Apple Push Notification System и Firebase Cloud Messaging. Для использования FCM необходимо импортировать библиотеку Firebase.
2. Добавление Push Notifications в проект
Необходимо добавить пуш-уведомления в ваш проект, чтобы пользователь мог получать их. Для этого зайдите в Targets на ваш проект и выберите раздел Signing & Capabilities. Далее в Capabilities добавьте Push Notifications. В этом разделе укажите ваш Team. А также укажите ваш BundleID в разделе General.
Для использования FCM в приложении необходимо загрузить GoogleService-Info.plist из консоли Firebase и поместить его в папку с приложением (предварительно в консоли должен быть добавлен сертификат .p8 для приложения).
3. Регистрация приложения в Apple Push Notification Service (APNs)
Регистрация необходима для подготовки приложения к работе с пуш-уведомлениями. Для этого добавьте в AppDelegate следующий код:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { PushNotificationService.setAccount("account") PushNotificationService.registerForPushNotifications() if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] { PushNotificationService.notificationData(notification) } return true }
При использовании FCM метод будет выглядеть следующим образом:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { PushNotificationService.setAccount("account") PushNotificationService.registerForPushNotifications() FirebaseApp.configure() Messaging.messaging().delegate = self if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] { PushNotificationService.notificationData(notification) } return true }
где account - системное имя вашего аккаунта в enKod (запросите у персонального менеджера)
Данный метод запросит у пользователя разрешение на отправку уведомлений при первом запуске и в случае одобрения пользователя зарегистрирует приложение в APNs. Далее, если у приложения будет доступ к отправке уведомлений, при следующих запусках приложения будет происходить только регистрация приложения в APNs.
4. Регистрация device token приложения
Для отправки пуш-уведомления необходим device token вашего приложения. Чтобы зарегистрировать его, добавьте следующий код в AppDelegate:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { PushNotificationService.setDeviceToken(deviceToken, account: "account") }
При использовании FCM метод будет выглядеть следующим образом:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { Messaging.messaging().apnsToken = deviceToken }
Данный метод позволяет обработать device token и отправить его к провайдеру с заданным заголовком account.
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Failed to register: \(error)") }
Данный метод выдаст ошибку при получении device token.
Также для использования FCM необходимо добавить следующее расширение:
extension AppDelegate: MessagingDelegate { func messaging( _ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { PushNotificationService.setDeviceToken(fcmToken ?? "") } }
5. Настройка обработки открытия push-уведомления
Добавьте следующий код в соответствующие методы AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { PushNotificationService.registerForPushNotifications() UNUserNotificationCenter.current().delegate = self if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] { PushNotificationService.notificationData(notification, account: "account") } return true }
Данный метод AppDelegate вызовется тогда, когда приложение полностью выгружено из памяти и происходит нажатие на уведомление. Также необходимо объявить делегата, чтобы обрабатывать и другие сценарии нажатия на пуш-уведомление.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { PushNotificationService.notificationData(userInfo, account: "account") completionHandler(.newData) } extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let notification = response.notification.request.content.userInfo PushNotificationService.notificationData(notification, account: "account") completionHandler() } }
где account - системное имя вашего аккаунта в enKod (запросите у персонального менеджера)
Данные методы AppDelegate вызываются тогда, когда приложение находится в активном состоянии и происходит нажатие на уведомление.
6. Изменение ключа в Info.plist для корректной работы URL запросов
Необходимо зайти в файл Info.plist и добавить следующий ключ со значением:
7. Настройка отображения пуш-уведомления при открытом приложении
Добавьте следующий метод UNUserNotificationCenterDelegate в AppDelegate:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { if #available (iOS 14.0, *) { completionHandler ([. list, .banner, .sound]) } else { completionHandler ([. alert, .badge, .sound]) } }
Данный метод позволяет настроить появления уведомления даже при открытом приложении.
8. Подключение Deeplink в проект
Пуш-уведомления могут содержать в себе deeplink. Для того, чтобы получить информацию о deeplink в пуш-уведомлении необходимо добавить следующий код:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() PushNotificationService.subscribeDeeplink(self) } } extension ViewController: PushNotificationServiceDelegate { func getDeeplink(_ deeplink: String) { print(deeplink) } }
Для начала нужно подписаться на получение deeplink, а далее при отправке push с зашитым значением deeplink будет вызываться метод getDeeplink, который имеет параметр со значением deeplink в виде строки. Чтобы отписаться от получения deeplink добавьте следующий код:
PushNotificationService.unsubscribeDeeplink()
Примечание: стоит отметить, что получения значения deeplink возможно только, если пуш хранит в себе информацию о deeplink. В остальных случаях метод getDeeplink вызываться не будет.
9. Модель пуш-уведомления
Можно получить модель пуш-уведомления, подписавшись на делегат PushNotificationServiceDelegate:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() PushNotificationService.subscribeDeeplink(self) } } extension ViewController: PushNotificationServiceDelegate { func getPushData(_ pushData: PushData) { print(pushData) } }
10. Отписка от пушей
Для возможности отписаться от пушей вызовите метод и передайте в него значение account.
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() SessionService.delegate = self PushNotificationService.unsubscribePush(account: "account") } } extension ViewController: SessionServiceDelegate { func sessionCreated() { } func sessionStarted() { } func pushSubscribed() { } func pushUnsubscribed() { } func pushClicked() { } func tokenRefreshed() { } func failure(error: Error) { } }
где account - системное имя вашего аккаунта в enKod (запросите у персонального менеджера)
Методы и условия срабатывания:
sessionCreated
сессия успешно создана и ID сессии, также как и token, хранятся в UserDefaultssessionStarted
сессия с ранее созданным ID успешно началасьpushSubscribed
подписка на пуш-уведомления успешно завершенаpushUnsubscribed
отписка на пуш-уведомления успешно завершенаpushClicked
действие пуш-уведомления успешно отправлено на серверtokenRefreshed
обновился токен и был отправлен на серверfailure
в одном из запросов произошла ошибка
Для получения sessionID используйте следующий код:
PushNotificationService.getSessionID
Для получения token используйте следующий код:
PushNotificationService.getToken
11. Обработка RichPush
Для того чтобы реализовать возможность разворачивания пуш-уведомления с изображением, необходимо добавить таргет Notification Service Extension, в котором необходимо переопределить метод didReceive.
Для работы данного функционала необходимо передавать следующие поля:
"image_url" | адрес изображения, по которому будет загружаться отображаемое изображение |
"mutable-content" | true, для возможности модификации принятого пуша перед его показом |
Для динамической обработки кнопок в уведомлении должно содержаться поле «buttons» со следующей структурой:
[{ "id": "button1", "label": "text on button", "action": "",??? "link": "https://somewhere.com" / "https://testApp/mainScreen" }]
Так же необходимо зарегистрировать категории уведомлений с действиями, создаваемыми на основе передаваемых кнопок. Пример обработки кнопок:
if let buttons = apnsData["buttons"] as? [Any] { var acts: Array = [] for b in buttons{ let but = b as? NSDictionary let id = but?["id"] as! String let title = but?["label"] as! String let action = UNNotificationAction(identifier: id, title: title, options: [.foreground])//.foreground нужен для открытия приложения перед открытием ссылки acts.append(action) } let cat = UNNotificationCategory(identifier: "cat1", actions: acts, intentIdentifiers: [], options: []) var categories = Set() categories.insert(cat) UNUserNotificationCenter.current().setNotificationCategories(categories) }else{ var categories = Set() categories.insert(UNNotificationCategory(identifier: "cat1", actions: [], intentIdentifiers: [], options: [])) UNUserNotificationCenter.current().setNotificationCategories(categories) }
Модель пуш-уведомлений
Модель сообщения
{ "aps": { "alert": { "title": "Title", "subtitle": "Subtitle", "body": "Body" }, "buttons":[ { "id": "button1", "label": "text on button", "action": "",??? "link": "https://somewhere.com" }, { "id": "button1", "label": "text on button", "action": "",??? "link": "https://somewhere.com" } ] "sound": "default", "badge": 12, "category": "CATEGORY", "personId": "123", "messageId": "321", "intent" : "0", "url": "https://url.com", "mutable-content": 1, "image-url": "https://picture.com" } }
Значение данных
"alert" | информация для отображения уведомлений |
"title" | заголовок уведомления |
"subtitle" | подзаголовок уведомления. Дополнительная информация |
"body" | содержание уведомления |
"sound" | звук уведомления. Если параметр не передавать, то звука при получения уведомления не будет |
"badge" | число, отображаемое на значке приложения. Укажите, 0, чтобы удалить текущий значок, если он есть |
"category" | тип уведомления. Эта строка должна соответствовать identifier одному из объектов, которые вы регистрируете во время запуска |
"personId" | ID пользователя |
"messageId" | ID сообщения |
"intent" | действие, которое будет выполнено по нажатию по пушу. Если «0», то произойдет открытие приложения с передачей туда динамической ссылки для дальнейшей ее обработке, если «1» - открытие ссылки в браузере, если «2» - будет открыто приложения |
"url" | ссылка динамическая или для открытия в браузере |
"mutable-content" | флаг, разрешающий изменять содержимое пуша перед его показом. Используется для возможности показывать большое изображение при нажатии (удержании) на пуш (Rich push) |
"image-url" | ссылка, содержащая адрес изображения в пуше. Применяется для показа большого изображения при нажатии (удержании) на пуш |