Pushed Messaging iOS Library
Полнофункциональная iOS библиотека для работы с Pushed Messaging, поддерживающая как традиционные APNS push-уведомления, так и современные WebSocket соединения для real-time messaging.
Возможности
📱 APNS Push Notifications
- Автоматическая регистрация устройства для push-уведомлений
- Подтверждение доставки и взаимодействия с сообщениями
- Поддержка rich notifications с изображениями и действиями
- Обработка background notifications
🔌 WebSocket Real-time Messaging (iOS 13.0+)
- Постоянное соединение для мгновенной доставки сообщений
- Автоматическое переподключение при потере соединения
- Управление состоянием соединения (фон/активное приложение)
- Обработка сообщений в real-time без задержек
🔧 Notification Service Extension
- Автоматическое подтверждение push-уведомлений в фоне
- Безопасное хранение токенов в Keychain
- Работа независимо от основного приложения
🔐 Безопасность
- Хранение токенов в iOS Keychain
- Шифрованная передача данных
- Basic Authentication для API запросов
Установка
CocoaPods
Добавьте в ваш Podfile
:
pod 'PushedMessagingiOSLibrary', :git => 'https://github.com/PushedLab/Pushed.Messaging.iOS.Library.git'
Затем выполните:
pod install
Требования
- iOS 11.0+
- WebSocket функциональность требует iOS 13.0+
- Xcode 12.0+
- Swift 5.0+
Быстрый старт
1. Настройка основного приложения
import SwiftUI
import PushedMessagingiOSLibrary
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
// Настройка делегата для уведомлений
UNUserNotificationCenter.current().delegate = self
// Инициализация библиотеки (упрощённый вызов)
// Режимы:
// - useAPNS: true + enableWebSocket: true → APNS + WebSocket (оба канала)
// - useAPNS: false + enableWebSocket: true → Только WebSocket (без APNS)
// - useAPNS: true + enableWebSocket: false → Только APNS
PushedMessagingiOSLibrary.setup(self, useAPNS: true, enableWebSocket: true)
// Дополнительно: настройка коллбеков WebSocket (iOS 13.0+)
if PushedMessagingiOSLibrary.isWebSocketAvailable { setupWebSocketCallbacks() }
return true
}
// Получение клиентского токена
@objc func isPushedInited(didRecievePushedClientToken pushedToken: String) {
print("Client token: \(pushedToken)")
// Сохраните токен для отправки сообщений конкретному пользователю
}
// Обработка входящих push-уведомлений
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Received push notification: \(userInfo)")
completionHandler(.newData)
}
// Обработка клика по уведомлению
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("User clicked notification: \(response.notification.request.content.userInfo)")
// Подтверждение взаимодействия с уведомлением
PushedMessagingiOSLibrary.confirmMessage(response)
completionHandler()
}
// Настройка WebSocket callbacks
private func setupWebSocketCallbacks() {
// Отслеживание статуса соединения
PushedMessagingiOSLibrary.onWebSocketStatusChange = { status in
print("WebSocket status: \(status.rawValue)")
}
// Обработка входящих WebSocket сообщений
PushedMessagingiOSLibrary.onWebSocketMessageReceived = { messageJson in
print("WebSocket message received: \(messageJson)")
// Обработайте сообщение в вашем приложении
// Верните true если сообщение обработано, false для показа стандартного уведомления
return self.handleWebSocketMessage(messageJson)
}
}
private func handleWebSocketMessage(_ messageJson: String) -> Bool {
// Ваша логика обработки WebSocket сообщений
do {
let data = messageJson.data(using: .utf8)!
let message = try JSONSerialization.jsonObject(with: data) as? [String: Any]
// Обработка сообщения...
return true // Сообщение обработано
} catch {
print("Error parsing WebSocket message: \(error)")
return false // Показать стандартное уведомление
}
}
}
📎 Привязка токена к Application ID
Если в вашем аккаунте Pushed создано несколько приложений, вы можете сразу привязать клиентский токен к конкретному приложению. Для этого перед первым запросом токена передайте applicationId
.
// Сразу после PushedMessagingiOSLibrary.setup(...)
PushedMessagingiOSLibrary.refreshTokenWithApplicationId("YOUR_APPLICATION_ID")
Библиотека отправит параметр applicationId
в запросе POST /v2/tokens
, и полученный токен будет мгновенно закреплён за выбранным приложением в системе Pushed.
Если строка пуста или nil
, будет использовано поведение по умолчанию — токен привяжется к приложению, отмеченному как Default в вашем личном кабинете.
2. Настройка Notification Service Extension (рекомендуется)
Создание Extension
- В Xcode: File → New → Target → Notification Service Extension
- Замените содержимое
NotificationService.swift
на актуальную реализацию:
import UserNotifications
import Foundation
import PushedMessagingiOSLibrary
@objc(NotificationService)
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
guard let bestAttemptContent else {
contentHandler(request.content)
return
}
// Подтверждение доставки сообщения через библиотеку
if let messageId = request.content.userInfo["messageId"] as? String {
PushedMessagingiOSLibrary.confirmDelivery(messageId: messageId)
}
contentHandler(bestAttemptContent)
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
// Дополнительный код не требуется — библиотека выполнит подтверждение
}
Настройка Keychain Sharing
⚠️ Важно: Для корректной работы Extension необходимо настроить общий доступ к Keychain:
В основном приложении:
- Перейдите в Signing & Capabilities
- Добавьте Keychain Sharing capability
- Добавьте keychain group:
$(AppIdentifierPrefix)com.yourcompany.yourapp.shared
В Notification Service Extension:
- Перейдите в Signing & Capabilities
- Добавьте Keychain Sharing capability
- Добавьте тот же keychain group:
$(AppIdentifierPrefix)com.yourcompany.yourapp.shared
Без этой настройки Extension не сможет получить доступ к токену, сохраненному основным приложением.
Настройка в основном приложении
// Указать что Extension обрабатывает подтверждения
PushedMessagingiOSLibrary.extensionHandlesConfirmation = true
WebSocket функциональность
Проверка доступности
if PushedMessagingiOSLibrary.isWebSocketAvailable {
// WebSocket доступен (iOS 13.0+)
PushedMessagingiOSLibrary.enableWebSocket()
} else {
print("WebSocket requires iOS 13.0 or later")
}
Управление соединением
// Включить/отключить WebSocket на лету
PushedMessagingiOSLibrary.enableWebSocket() // эквивалентно enableWebSocket: true
PushedMessagingiOSLibrary.disableWebSocket()
// Проверить статус
let status = PushedMessagingiOSLibrary.webSocketStatus
print("Current status: \(status.rawValue)")
// Получить диагностику
if #available(iOS 13.0, *) {
let diagnostics = PushedMessagingiOSLibrary.getWebSocketDiagnostics()
print(diagnostics)
}
APNS функциональность
Управление APNS push-уведомлениями
// Включить APNS push-уведомления (включено по умолчанию)
PushedMessagingiOSLibrary.enableAPNS()
// Проверить статус APNS
let isEnabled = PushedMessagingiOSLibrary.isAPNSEnabled
print("APNS enabled: \(isEnabled)")
Сценарии использования
Полный режим (APNS + WebSocket):
// Через setup:
PushedMessagingiOSLibrary.setup(self, useAPNS: true, enableWebSocket: true)
// Или включить на лету:
PushedMessagingiOSLibrary.enableAPNS()
if PushedMessagingiOSLibrary.isWebSocketAvailable { PushedMessagingiOSLibrary.enableWebSocket() }
Только WebSocket (без push-уведомлений):
// Через setup:
PushedMessagingiOSLibrary.setup(self, useAPNS: false, enableWebSocket: true)
// Или переключить на лету:
PushedMessagingiOSLibrary.disableAPNS()
if PushedMessagingiOSLibrary.isWebSocketAvailable { PushedMessagingiOSLibrary.enableWebSocket() }
Только APNS (классический режим):
// Через setup:
PushedMessagingiOSLibrary.setup(self, useAPNS: true, enableWebSocket: false)
// Или переключить на лету:
PushedMessagingiOSLibrary.enableAPNS()
PushedMessagingiOSLibrary.disableWebSocket()
Обработка сообщений
PushedMessagingiOSLibrary.onWebSocketMessageReceived = { messageJson in
// Разбор JSON сообщения
guard let data = messageJson.data(using: .utf8),
let message = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
return false
}
// Обработка различных типов сообщений
switch message["type"] as? String {
case "notification":
handleNotificationMessage(message)
return true
case "data":
handleDataMessage(message)
return true
default:
return false // Показать стандартное уведомление
}
}
API Reference
Основные методы
// Инициализация библиотеки (упрощённая форма)
PushedMessagingiOSLibrary.setup(_ appDelegate: UIApplicationDelegate,
useAPNS: Bool,
enableWebSocket: Bool)
// Инициализация (расширенная форма с дополнительными опциями)
PushedMessagingiOSLibrary.setup(_ appDelegate: UIApplicationDelegate,
askPermissions: Bool = true,
loggerEnabled: Bool = false,
useAPNS: Bool = true,
enableWebSocket: Bool = false)
// Получение клиентского токена
let token = PushedMessagingiOSLibrary.clientToken
// Подтверждение сообщения по клику
PushedMessagingiOSLibrary.confirmMessage(_ response: UNNotificationResponse)
// Запрос разрешений на уведомления (если нужно вручную)
PushedMessagingiOSLibrary.requestNotificationPermissions()
// Получение логов (для отладки)
let logs = PushedMessagingiOSLibrary.getLog()
Callback'и
// Статус WebSocket соединения
PushedMessagingiOSLibrary.onWebSocketStatusChange = { status in
// .connecting, .connected, .disconnected
}
// Входящие WebSocket сообщения
PushedMessagingiOSLibrary.onWebSocketMessageReceived = { messageJson in
// Верните true если сообщение обработано
return false
}
Конфигурация
Настройки уведомлений
// Отключить дублирование подтверждений (если используется Extension)
PushedMessagingiOSLibrary.extensionHandlesConfirmation = true
// Включить подробное логирование (пример):
PushedMessagingiOSLibrary.setup(self, askPermissions: true, loggerEnabled: true, useAPNS: true, enableWebSocket: false)
Очистка данных (для тестирования)
// Очистить токен для тестирования
PushedMessagingiOSLibrary.clearTokenForTesting()
Troubleshooting
WebSocket проблемы
WebSocket не подключается:
- Проверьте интернет соединение
- Убедитесь что iOS 13.0+
- Проверьте что клиентский токен получен
- Посмотрите диагностику:
getWebSocketDiagnostics()
Частые переподключения:
- Проверьте стабильность сети
- Убедитесь что приложение не блокирует фоновые процессы
APNS проблемы
Push-уведомления не приходят:
- Проверьте capabilities: Push Notifications
- Убедитесь что сертификаты настроены правильно
- Проверьте что устройство зарегистрировано для уведомлений
Дублирование подтверждений:
- Установите
extensionHandlesConfirmation = true
- Используйте либо Extension, либо основное приложение для подтверждений
Extension проблемы
Extension не получает токен:
- Убедитесь что основное приложение запускалось хотя бы один раз
- Проверьте Keychain Sharing в capabilities
- Убедитесь что Extension имеет доступ к Keychain
Примеры использования
Полные рабочие примеры доступны в папке /Example
данного репозитория.
Лицензия
Этот проект распространяется под лицензией MIT. См. файл LICENSE
для подробностей.
Поддержка
Для получения дополнительной информации посетите сайт Pushed или создайте issue в данном репозитории.